値を返すメソッド(たとえば、Remove
メソッドのDictionary
クラスがbool
を返した場合)、戻り値を変数に代入しないとどうなりますか?つまり、を結果にbool
変数を代入しないで書くと、bool b = dictionary.Remove("plugin-01");
に関するコンパイルの違いは何ですか?コンパイルされたメソッド呼び出しはどのように値を返しますか?
答えて
を書くことができます
if(!dictionary.Remove("plugin-01")) {
MessageBox.Show("Error: plugin-01 does not exist!");
}
ような何かを行うことができます)
void Main()
{
Bar();
Baz();
}
bool Bar()
{
return true;
}
void Baz()
{
Console.WriteLine("placeholder");
}
これは、次のILを生成します。
IL_0000: ldarg.0
IL_0001: call UserQuery.Bar
IL_0006: pop //remove current value from evaluation stack
IL_0007: ldarg.0
IL_0008: call UserQuery.Baz
Bar:
IL_0000: ldc.i4.1
IL_0001: ret
Baz:
IL_0000: ldstr "placeholder"
IL_0005: call System.Console.WriteLine
IL_000A: ret
Bar
が呼び出され、評価スタックからブール値の戻り値を削除するポップが表示されます。これはどこにもありません。例を更新してBaz()
への別のメソッド呼び出しを追加しなければならなかった。さもなければ、プログラムが終了するので、popは出されないだろう。
今の私たちが実際に戻り値を使用する場合を見てみましょう:
void Main()
{
bool foo = Bar();
Console.WriteLine(foo);
}
bool Bar()
{
return true;
}
これは、次のILを生成します。
IL_0000: ldarg.0
IL_0001: call UserQuery.Bar
IL_0006: stloc.0 //pops current value from evaluation stack, stores in local var
IL_0007: ldloc.0
IL_0008: call System.Console.WriteLine
Bar:
IL_0000: ldc.i4.1
IL_0001: ret
はIL_007
を含めた後、すべてとあるSystem.Console.WriteLine
一部を無視します - コンパイラが変数の使用を最適化しないように、それを追加するだけでした。 Bar
メソッド呼び出しの結果が評価スタックからポップされ、ローカル変数foo
に格納されていることがわかります。それは戻り値を取得して取り除くpop
か、結果を変数に代入するためにstloc.0
のいずれかです。
したがって、メソッド呼び出しの結果が必要ない場合は、結果を無視するだけです。結果を変数に代入してその変数を使用しなくても、コンパイラは変数と割り当てを完全に最適化することができます(少なくともデバッグモードではデバッグ経験を向上させるためにほとんどの最適化が無効になります)。
戻り値は、使用しない場合は無視されます。
あなたは気にしない場合、あなたは安全のは、それがLinqPadの(礼儀を生産している簡単な例とILコードを見てみましょう
dictionary.Remove("plugin-01");
呼び出し部分は同じですが、割り当て部分はILでスキップされます。見てください - ここでは簡単なプログラムの解体である:解体はこのようになります
var d = new Dictionary<int,int>();
bool a = d.Remove(5);
d.Remove(6);
:
bool a = d.Remove(5);
00000057 mov ecx,dword ptr [ebp-40h]
0000005a mov edx,5
0000005f cmp dword ptr [ecx],ecx
00000061 call 69106A00
// Here is the assignment part
00000066 mov dword ptr [ebp-4Ch],eax
00000069 movzx eax,byte ptr [ebp-4Ch]
0000006d mov dword ptr [ebp-44h],eax
d.Remove(6);
00000070 mov ecx,dword ptr [ebp-40h]
00000073 mov edx,6
00000078 cmp dword ptr [ecx],ecx
0000007a call 69106A00
トップの4行は共通しています。最初のコールから最後の3行が割り当てを処理します。 2回目の呼び出しの分解では欠落しています。
- 1. メソッドは呼び出し元メソッドで戻り値を返しますか? c#
- 2. メソッドの呼び出し元をトラッキングする[呼び出しによって呼び出された]
- 3. 値を返す同期された "呼び出し順序認識"メソッド
- 4. WebMethodは値を返し、vb.netの他のメソッドを呼び出す
- 5. このJavaメソッドはどのように呼び出されていますか?
- 6. 動的ディスパッチの場合、オーバーライドされたメソッドの呼び出しはどのように行われますか
- 7. Jade Agent:setup()メソッドはどのように呼び出されますか?
- 8. 呼び出された後、呼び出された関数はどのように呼び出し元に戻りますか?
- 9. 呼び出されたバットファイルをどのようにして呼び出すことができますか?
- 10. onCreateメソッドは、アクティビティクラスのonConfigurationChangedメソッドを呼び出した後に呼び出されます。
- 11. メソッド呼び出しの返された値の完全な配列を更新するにはどうすればよいですか?
- 12. backgroundWorkerの外部クラスから呼び出されたメソッドからフォーム上のメソッドを呼び出すにはどうすればよいですか?
- 13. オーバーライドされたメソッドを呼び出すと、オーバーライドされた呼び出しメソッドのスーパークラス
- 14. NoSuchMethodErrorがloader.loadClass()の呼び出しによって呼び出されました。
- 15. 呼び出されたアクティビティから値を返す
- 16. メソッドの呼び出しはC#でスキップされますか?
- 17. eclipseとは別にメソッド呼び出しをどのように呼びますか?
- 18. コンパイルされたJavaクラス内でのメソッド呼び出しの書き換え
- 19. メソッド呼び出しをどのようにチェーンできますか?
- 20. ハッシュ値であるメソッドをどのように呼び出すのですか?
- 21. jsはどのようにUIWebViewのメソッドを呼び出して戻り値を取得できますか?
- 22. 呼び出されたメソッドの戻り値を渡すstd :: enable_if_t
- 23. viewpagerのgetItemメソッドが2回呼び出されました。どのように二度目の呼び出しを避けるため
- 24. 呼び出された(ディスパッチャを介して)呼び出し、または直接呼び出された呼び出しを同期する
- 25. ajax呼び出しのイベントバインド - どのようにしますか?
- 26. ネイティブフェッチAPIが私の呼び出しを返さないようにします
- 27. アプリケーションがバックグラウンドから呼び出されたときにメソッドを呼び出す
- 28. DisplayObjectContainerでaddChildメソッドまたはremoveChildメソッドが呼び出された場合はどうなりますか?
- 29. ActiveRecordはチェーン内の最後のメソッド呼び出しをどのように検出しますか?
- 30. クラスdraw()メソッドは直接呼び出されたときに機能しますが、別のオブジェクトによって呼び出されるとクラッシュします
'Console.WriteLine(foo)'を削除すると、ILは最初の例と同じになるはずですか? – enzom83
はい、それはある - 変数 'foo'が使用されることはありませんので、それは(おそらく)離れて最適化されています。 「これは、次のILを生成し、」あなたの最初で – BrokenGlass
は、私はあなたが呼び出しに続くPOP命令を含めるべきだと思います。 - しかし、あなたはありLinqPadによって生成されるよう、私は完全なIL出力を示した。これは、メソッドの結果は、MSILをスタック上にあり、呼び出し側が –