Es posible declarar una función lambda e inmediatamente llamarla:
Func<int, int> lambda = (input) => { return 1; };
int output = lambda(0);
Me pregunto si es posible hacerlo en una línea, por ejemplo, algo como
int output = (input) => { return 1; }(0);
que da un error del compilador "Nombre del método esperado". Lanzar a Func<int, int>
tampoco funciona:
int output = (Func<int, int>)((input) => { return 1; })(0);
da el mismo error y, por las razones mencionadas a continuación, me gustaría evitar tener que especificar explícitamente el tipo de argumento de entrada (el primero int
).
Probablemente se esté preguntando por qué quiero hacer esto, en lugar de simplemente incrustar el código directamente, por ejemplo int output = 1;
. La razón es la siguiente: he generado una referencia para un servicio web SOAP con svcutil
, que debido a los elementos anidados genera nombres de clase extremadamente largos, que me gustaría evitar tener que escribir. Entonces en lugar de
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()
};
y un CreateAddress(GetOrderResultOrderShipment_OrderShipmentShipment_Address address)
método separado (los nombres reales son aún más largos, y tengo un control muy limitado sobre el formulario), me gustaría escribir
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()
};
Se que podria escribir
Address = sh.ReceiverAddress_Shipment == null ? null : new Address {
Street = sh.ReceiverAddress_Shipment.Address.Street,
...
}
pero incluso eso (la sh.ReceiverAddress_Shipment.Address
parte) se vuelve muy repetitivo si hay muchos campos. Declarar una lambda e inmediatamente llamarla sería más elegante, menos caracteres para escribir.
public T Exec<T>(Func<T> func) => return func();
Y usarlo así: int x = Exec(() => { return 1; });
eso para mí se lee mucho mejor que el casting con todos sus padres.
int output = ((Func<int>) (() => { return 1; }))();