Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to cast lambdas?

I'd like a family of functions to be kept in a dictionary that derive from some base type (lets call the base class "object" for example sake). So, it it possible to keep f1 in f2?

Func<bool> f1 = () => true;
Func<object> f2 = f1;

Error 1 Cannot implicitly convert type System.Func<bool> to System.Func<object>

Is this the best we can do?

Func<bool> f1 = () => true;
Func<object> f2 = () => (object)f1;

Errors: (none)

I guess what it needs to be generic friendly is a where statement... but I'm not sure if you can do that with lamdas.


Following up on Armen's info, I dug into the definitions of string and bool:

public sealed class String : IComparable, ICloneable, IConvertible, IEnumerable,
                             IComparable<String>, IEnumerabl<char>,
                             IEquatable<String> 

public struct Boolean : IComparable, IConvertible, IComparable<Boolean>,
                        IEquatable<Boolean>

He's right about ref Vs value. Does String derive from object implicitly? Looks like that is the behaviour for structs according to @PeterK's link.

"ValueType overrides the virtual methods from Object with more appropriate implementations for value types. See also Enum, which inherits from ValueType."

Object:

System.Object: All classes, structures, enumerations, and delegates. (from http://msdn.microsoft.com/en-us/library/system.object)

Which in turn makes Func<bool> not being assignable to Func<object> a little bit dumb. i.e. the inheritance hierarchy was correct from that point of view.

like image 576
sgtz Avatar asked Sep 08 '12 10:09

sgtz


People also ask

How do you call a lambda function in Java?

You can invoke a Lambda function by creating an AWSLambda object and invoking its invoke method. Create an InvokeRequest object to specify additional information such as the function name and the payload to pass to the Lambda function.

Can we use lambda without functional interface?

The Lambda expression is used to provide the implementation of an interface which has functional interface. It saves a lot of code. In case of lambda expression, we don't need to define the method again for providing the implementation.

How are lambdas implemented?

A lambda works like this: Generates invokedynamic call site and uses a lambdafactory to return the functional implementation. Lambda converted to a method to be invoked by invokedynamic. The method is stored in a class as a private static method.

Why do we use lambdas?

Lambda functions are intended as a shorthand for defining functions that can come in handy to write concise code without wasting multiple lines defining a function. They are also known as anonymous functions, since they do not have a name unless assigned one.


2 Answers

From here (emphasis mine):

Covariance enables you to use a more derived type than that specified by the generic parameter. This allows for implicit conversion of classes that implement variant interfaces and implicit conversion of delegate types. Covariance and contravariance are supported for reference types, but they are not supported for value types.

Also:

Variance applies only to reference types; if you specify a value type for a variant type parameter, that type parameter is invariant for the resulting constructed type.

The reason might have to do with how C# and the CLI historically deal (and don't agree) with array covariance of value types. Look here for some info.

So you see, the covariance of the type parameter in Func<out TResult> doesn't work with value types, so you have to do this:

Func<object> f2 = () => f1();
like image 173
Jordão Avatar answered Oct 14 '22 02:10

Jordão


If you are using .NET 4.0+, this is possible.

Your example doesn't work because bool is a value type. If you were to change bool with string, however, the sample works.

    Func<string> f1 = () => "true";
    Func<object> f2 = f1;
like image 42
armen.shimoon Avatar answered Oct 14 '22 00:10

armen.shimoon