Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implicit conversion from lambda expression to user-defined type

I want to define an implicit conversion from (specific) lambda expressions to a user-defined type. I tried the following:

public static implicit operator DualElement<T>(Func<OPTatom, OPTatom, T> atomMap)
{
    return new DualElement<T>(e => atomMap(e[0],e[1]));
}

Then I tried

DualElement<double> dubidu = (i, j) => cost[i, j];

which gives "Cannot convert lambda expression ... because it is not a delegate type"

Instead, what works is:

DualElement<double> dideldu = (Func<OPTatom, OPTatom, double>)((i, j) => cost[i, j]);

I guess, lambda expressions do not have the type 'Func' so that I have to put something different into the implicit conversion.

Can somebody give me a hint?

like image 755
J Fabian Meier Avatar asked Apr 28 '15 10:04

J Fabian Meier


People also ask

Is there an implicit conversion from dynamic to any type?

An implicit dynamic conversion exists from an expression of type dynamic to any type T . The conversion is dynamically bound §11.3. 3, which means that an implicit conversion will be sought at run-time from the run-time type of the expression to T .

What is an implicit conversion?

An implicit conversion sequence is the sequence of conversions required to convert an argument in a function call to the type of the corresponding parameter in a function declaration. The compiler tries to determine an implicit conversion sequence for each argument.

How do you convert lambda expressions?

To convert a lambda expression to a named methodMove to the labda expression you want to convert. From the Refactor menu of the VisualAid choose To Named Method. Telerik® JustCode™ will replace the lambda expression with a method group and will add a new method.

Can we write a Parameterless lambda expression?

No, there isn't. Lambda expressions are optimised (in terms of syntax) for the single parameter case. I know that the C# team feels your pain, and have tried to find an alternative. Whether there ever will be one or not is a different matter.


2 Answers

Your workaround is pretty good.
Lambdas have no type in themselves, so they should be casted to some appropriate type.
Please see MSDN:

Note that lambda expressions in themselves do not have a type because the common type system has no intrinsic concept of "lambda expression." However, it is sometimes convenient to speak informally of the "type" of a lambda expression. In these cases the type refers to the delegate type or Expression type to which the lambda expression is converted.

This is why the following example won't compile:

var func = (i, j) => i + j;
like image 169
Dmitry Avatar answered Oct 07 '22 13:10

Dmitry


You have defined implicit operator from Func<OPTatom, OPTatom, T> delegate type and trying to conversion from lambda expression which seems strange to C# compiler.

Instead store the lambda expression in some variable of type Func<OPTatom, OPTatom, T> and then perform implicit conversion. following will work here:

Func<OPTatom, OPTatom, T> temp = (i, j) => cost[i, j];
DualElement<double> dubidu = temp;

I created demo and it worked fine.

public class Program
{
    public static void Main()
    {
        Func<string, bool> func = d => true;
        Process<bool> p = func;
        //Process<bool> p = d => true; would result in error
    }
}

public class Process<T>
{
    public Process(T item)
    {
        Item = item;
    }

    public T Item
    {
        get;
        set;
    }

    public static implicit operator Process<T>(Func<string, T> func)
    {
        return new Process<T>(func("jenish"));
    }
}

Here is dotnetfiddle link in case you want to play with it.

like image 25
Jenish Rabadiya Avatar answered Oct 07 '22 13:10

Jenish Rabadiya