2013-08-22 14 views
5
private void SimpleLambda() 
{ 
    dynamic showMessage = x => MessageBox.Show(x); 

    showMessage("Hello World!"); 
} 

にエラーメッセージがある:それはデリゲート型ラムダ式とMessageboxはC#の

すべてのヘルプはないので は、ダイナミック型にラムダ式を変換できません、

+0

あるか 'アクション'や 'のFunc <文字列、DialogResult>'一般に –

+0

は、私はあなたが '通常のコードでは避けるべき高度な機能としてdynamic'を扱うお勧めします。 – Brian

答えて

5
private void SimpleLambda() 
{ 
    Action<string> showMessage = x => MessageBox.Show(x); 

    showMessage("Hello World!"); 
} 
4

あなたが宣言する必要がデリゲート型さもなければ、それはどんなタイプのラムダ式であろうと知らないでしょう— xは何でもよいです。これは動作するはずです:

Action<string> showMessage = x => MessageBox.Show(x); 

は、このデリゲート型が何であるかを明確にするためにAction<T>を参照してください。

16

これはMessageBoxとは何の関係もありません。エラーメッセージによれば、ラムダ式をdynamicに変換することはできません。なぜなら、コンパイラはインスタンスを作成する委任タイプを知らないからです。

あなたが欲しい:でも

Action<string> action = x => MessageBox.Show(x); 

またはメソッドグループの変換を使用し、その後、あなたは戻り値の型と一致しなければなりませんが、:あなたはその後、使用dynamicあなたが望むことができるかどう

Func<string, DialogResult> func = MessageBox.Show; 

を:

dynamic showMessage = action; // Or func 
showMessage("Hello World!"); 

また、明示的なデリゲートのインスタンス式でラムダ式をpecify:

dynamic showMessage = new Action<string>(x => MessageBox.Show(x)); 
+5

+1のためにJon Skeetによって回答されました:) –

+0

-1これは 'Action 'で動作しません。 –

+0

なぜ動作しませんか? – speti43

1

私は、このための型推論ヘルパーを作成しました。私は一時変数に保存したい場合、私は

var fn = Func.F((string x) => MessageBox.Show(x)); 

または

var fn = Func.F((double x, double y) => x + y); 

を書くあなたはまだ、パラメータsignitureに配置する必要がありますので、実際にラムダの署名を入力して好きではないが、あなた戻り値の型を型推論で扱います。

実装は

using System; 

namespace System 
{ 
    /// <summary> 
    /// Make type inference in C# work harder for you. Normally when 
    /// you want to declare an inline function you have to type 
    /// 
    ///  Func<double, double, double> fn = (a,b)=>a+b 
    /// 
    /// which sux! With the below methods we can write 
    /// 
    ///  var fn = Func.F((double a, double b)=>a+b); 
    /// 
    /// which is a little better. Not as good as F# type 
    /// inference as you still have to declare the args 
    /// of the function but not the return value which 
    /// is sometimes not obvious straight up. Ideally 
    /// C# would provide us with a keyword fun used like 
    /// 
    ///  fun fn = (double a, double b)=>a+b; 
    /// 
    /// but till then this snippet will make it easier 
    /// 
    /// </summary> 
    public static class Func 
    { 
     public static Func<A> F<A>(Func<A> f) 
     { 
      return f; 
     } 
     public static Func<A,B> F<A, B>(Func<A, B> f) 
     { 
      return f; 
     } 
     public static Func<A,B,C> F<A, B,C>(Func<A, B,C> f) 
     { 
      return f; 
     } 
     public static Func<A,B,C,D> F<A,B,C,D>(Func<A,B,C,D> f) 
     { 
      return f; 
     } 
     public static Func<A,B,C,D,E> F<A,B,C,D,E>(Func<A,B,C,D,E> f) 
     { 
      return f; 
     } 

     public static Action A(Action f) 
     { 
      return f; 
     } 
     public static Action<_A> A<_A>(Action<_A> f) 
     { 
      return f; 
     } 
     public static Action<_A,B> A<_A, B>(Action<_A, B> f) 
     { 
      return f; 
     } 
     public static Action<_A,B,C> A<_A, B,C>(Action<_A, B,C> f) 
     { 
      return f; 
     } 
     public static Action<_A,B,C,D> A<_A,B,C,D>(Action<_A,B,C,D> f) 
     { 
      return f; 
     } 
     public static Action<_A,B,C,D,E> A<_A,B,C,D,E>(Action<_A,B,C,D,E> f) 
     { 
      return f; 
     } 
    } 

}