2017-03-05 9 views
2

おはようございます!私は2つの亜種にラムダ式を含む、機能を持っていること、のは、言ってみましょう:C#ラムダ式が "空"かどうかを確認するには?

DoSomething('a', x => { }); 
DoSomething('b', x => { Console.WriteLine(x); }) 

遠くプログラムで、私は式の方法は、いくつかのコードを含むか否かに基づいて、いくつかのアクションを実行する必要があります。私の考えでは、これは次のようになっているはずです。

public void DoSomething (char symbol, Action<string> execute) 
    { 
     if (execute.Method.IsEmpty) 
      DoThis(...) 
     else 
      DoThat(...) 
    } 

もちろん、私はこれを正確に書くことができません。では、関数にコマンドがあるかどうかをどうやって確認できますか?

+4

代わりにDoSomething( 'a'、null)を使用してください。今は簡単です。 –

+0

渡されている 'Action'は他の関数と同じです。あなたが何をしているのかを知ることはできません。呼び出し側が 'Action'を提供するパスと、呼び出し側が何も提供しない別のパスを持つ必要がある場合は、' Action'を取らないメソッドオーバーロードを提供してください。 –

答えて

-1

あなたは、アクションの対応ILを見てみてください可能性があります

public void DoSomething(char symbol, Action<string> execute) 
{ 
    byte[] body = execute.Method.GetMethodBody().GetILAsByteArray(); 
    if ((body.Length == 1 && body[0] == 42) || (body.Length == 2 && body[0] == 0 && body[1] == 42)) 
    { 
     // 0 - no op 
     // 42 - return 
     DoThis(...) 
    } 
    else 
    { 
     DoThat(...) 
    } 
} 
+3

これは恐ろしいです。あなたはコード決定をするためにILを覗いてはいけません。アクションが何もしないメソッドを呼び出すとどうなりますか?あなたはそのように言うことはできません。 – siride

+0

アクションが何もしないメソッドを呼び出すと、最初のアクションは何かを行います。メソッドを呼び出します:-)また、リリースモードでは、呼び出し元のメソッドが空の場合、C#コンパイラは単純に最適化します。私はこれが非常に脆いことに同意しますが、残念なことにOPが私たちと分かち合っていない実際のシナリオによっては、知る価値があるかもしれません。 –

0

は、2つの独立した方法のように思える:

public void DoSomething (char symbol) 
{ 
    DoThis() 
} 

public void DoSomething (char symbol, Action<string> execute) 
{ 
    if (execute == null) /* handle null case */ 
     DoThis() 
    else 
     DoThat() 
} 

別のオプションは、オプションのパラメータかもしれない(そして、あなたはどちらかはnullをチェックする必要がありますway):

public void DoSomething (char symbol, Action<string> execute = null) 
{ 
    if (execute == null) 
     DoThis() 
    else 
     DoThat() 
} 
関連する問題