It's possible to declare a lambda function and immediately call it:
Func<int, int> lambda = (input) => { return 1; };
int output = lambda(0);
I'm wondering if it's possible to do so in one line, e.g. something like
int output = (input) => { return 1; }(0);
which gives a compiler error "Method name expected". Casting to Func<int, int>
doesn't work either:
int output = (Func<int, int>)((input) => { return 1; })(0);
gives the same error, and for reasons mentioned below I'd like to avoid having to explicitly specify the input argument type (the first int
).
You're probably wondering why I want to do this, instead of just embedding the code directly, e.g. int output = 1;
. The reason is as follows: I've generated a reference for a SOAP webservice with svcutil
, which because of the nested elements generates extremely long class names, which I'd like to avoid having to type out. So instead of
var o = await client.GetOrderAsync(request);
return new Order {
OrderDate = o.OrderDate,
...
Shipments = o.Shipment_Order == null ? new Shipment[0]
o.Shipment_Order.Select(sh => new Shipment {
ShipmentID = sh.ShipmentID,
...
Address = CreateAddress(sh.ReceiverAddress_Shipment);
}).ToArray()
};
and a separate CreateAddress(GetOrderResultOrderShipment_OrderShipmentShipment_Address address)
method (real names are even longer, and I have very limited control about the form), I'd like to write
var o = await client.GetOrderAsync(request);
return new Order {
OrderDate = o.OrderDate,
...
Shipments = o.Shipment_Order == null ? new Shipment[0]
o.Shipment_Order.Select(sh => new Shipment {
ShipmentID = sh.ShipmentID,
...
Address = sh.ReceiverAddress_Shipment == null ? null : () => {
var a = sh.ReceiverAddress_Shipment.Address;
return new Address {
Street = a.Street
...
};
}()
}).ToArray()
};
I know I could write
Address = sh.ReceiverAddress_Shipment == null ? null : new Address {
Street = sh.ReceiverAddress_Shipment.Address.Street,
...
}
but even that (the sh.ReceiverAddress_Shipment.Address
part) becomes very repetitive if there are many fields. Declaring a lambda and immediately calling it would be more elegant less characters to write.
The const keyword Variables can be declared as constants by using the “const” keyword before the datatype of the variable. The constant variables can be initialized once only. The default value of constant variables are zero.
A declaration is a C language construct that introduces one or more identifiers into the program and specifies their meaning and properties. Declarations may appear in any scope.
In C language, a variable name can consists of letters, digits and underscore i.e. _ . But a variable name has to start with either letter or underscore. It can't start with a digit. So valid variables are var_9 and _ from the above question.
Instead of trying to cast the lambda, I propose you use a small helper function:
public static TOut Exec<TIn, TOut>(Func<TIn, TOut> func, TIn input) => func(input);
which you could then use like this: int x = Exec(myVar => myVar + 2, 0);
. This reads a lot nicer to me than the alternatives suggested here.
It's ugly, but it's possible:
int output = ((Func<int, int>)(input => { return 1; }))(0);
Anonymous functions, including lambda expressions, are implicitly convertible to a delegate that matches their signature, but this syntax requires the lambda to be enclosed in parentheses.
The above can be simplified as well:
int output = ((Func<int, int>)(input => 1))(0);
Lambda literals in C# have a curious distinction in that their meaning is dependent on their type. They are essentially overloaded on their return type which is something does not exist anywhere else in C#. (Numeric literals are somewhat similar.)
The exact same lambda literal can either evaluate to an anonymous function that you can execute (i.e. a Func
/Action
) or an abstract representation of the operations inside of the Body, kind of like an Abstract Syntax Tree (i.e. a LINQ Expression Tree).
The latter is, for example, how LINQ to SQL, LINQ to XML, etc. work: the lambdas do not evaluate to executable code, they evaluate to LINQ Expression Trees, and the LINQ provider can then use those Expression Trees to understand what the body of the lambda is doing and generate e.g. a SQL Query from that.
In your case, there is no way for the compiler to know wheter the lambda literal is supposed to be evaluated to a Func
or a LINQ Expression. That is why Johnathan Barclay's answer works: it gives a type to the lambda expression and therefore, the compiler knows that you want a Func
with compiled code that executes the body of your lambda instead of an un-evaluated LINQ Expression Tree that represents the code inside the body of the lambda.
You could inline the declaration of the Func
by doing
int output = (new Func<int, int>(() => { return 1; }))(0);
and immediately invoking it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With