Question

I'm trying to create a class that takes a lambda and stores it internally. The syntax would be something like:

class Lambda<TIn, TOut> {
    private Expression<Func<TIn, TOut>> expr;
    private Func<TIn, TOut>> func;

    public Lambda(Expression<Func<TIn, TOut>> e) {
        expr = e;
    }

    public Lambda(Func<TIn, TOut> f) {
        func = f;
    }

    public static implicit operator Lambda<TIn, TOut>([lambdatype] o) {
        return new Lambda(o);
    }
}

Usage:

Lambda<TIn, TOut> l = o => ... ;

But I'm having some trouble figuring out the details. I know that a lambda is an anon type until it's assigned to either an expression or a delegate and that I would (I believe) have to use an implicit operator to get the syntax I'm going for, but beyond that I've hit a wall. I can use Expression or Func in my implicit operator if they've already been assigned to a variable like so:

Expression<Func<T1, T2>> e = o => ...;
Func<T1, T2> f = o => ...;

Lambda<T1, T2> l1 = e, l2 = f;

But I'd much prefer to just assign the lambda itself and have the class figure out the details.

Was it helpful?

Solution

Your problem is that the C# language does not chain user-defined implicit conversions.

Lambda expressions are untyped expressions that have implicit conversions to the (potentially infinite) set of compatible delegate & expression tree types. (see §6.5 of the spec)

You cannot invoke both that implicit conversion and the user-defined implicit conversion from a delegate type to your own type implicitly.

Instead, you can explicitly create a typed delegate:

Lambda<TIn, TOut> l = new Func<TIn, TOUt>(o => ... );

You could also ask the C# language team to define a syntax for user-defined implicit conversions from method groups or lambdas to any type.

OTHER TIPS

When you actually define the lambda expression it needs to be explicit (like an Action or Func ect). If you do that you can just assign directly to a property of type delegate.

 public class myClass
 {
     public Delegate myDelegate { get; set; }

     public myClass(Delegate d)
     {
         myDelegate = d;
     }
 }


 myClass myInstance = new myClass(new Func<int, int>(x => x * x));
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top