Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implicit Operators and lambdas

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.

like image 840
Damian Gray Avatar asked Feb 18 '14 18:02

Damian Gray


1 Answers

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.

like image 58
SLaks Avatar answered Sep 20 '22 11:09

SLaks