KekoSha
KekoSha

Reputation: 125

lambda expression and Messagebox in C#

private void SimpleLambda()
{
  dynamic showMessage =  x => MessageBox.Show(x);

  showMessage("Hello World!");
}

The Error message is : Can't convert lambda expression to dynamic type , because it is not a delegate type

Any help,

Upvotes: 5

Views: 1094

Answers (4)

Jon Skeet
Jon Skeet

Reputation: 1503270

This has nothing to do with MessageBox - as the error message says, you simply can't convert a lambda expression to dynamic as the compiler has no idea what delegate type to create an instance of.

You want:

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

Or even use a method group conversion, although then you have to match the return type:

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

You can then use dynamic if you want:

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

Alternatively, you can specify the lambda expression in an explicit delegate instance expression:

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

Upvotes: 16

bradgonesurfing
bradgonesurfing

Reputation: 32202

I created a type inference helper for this. I don't really like typing out the signature of lambdas if I want to store them in temporary variables so I write

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

or

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

You still have to put in the parameter signiture but you let type inference deal with the return type.

Implementation is

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; 
        }
    }

}

Upvotes: 1

speti43
speti43

Reputation: 3046

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

  showMessage("Hello World!");
}

Upvotes: 5

p.s.w.g
p.s.w.g

Reputation: 149058

You have to declare the delegate type. Otherwise it won't know what type of lambda expression it's supposed to be—x could be anything. This should work:

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

See Action<T> for clarification on what this delegate type is.

Upvotes: 4

Related Questions