Il est possible de déclarer une fonction lambda et de l'appeler immédiatement:
Func<int, int> lambda = (input) => { return 1; };
int output = lambda(0);
Je me demande s'il est possible de le faire sur une seule ligne, par exemple quelque chose comme
int output = (input) => { return 1; }(0);
ce qui donne une erreur de compilation "Nom de méthode attendu". La diffusion vers Func<int, int>
ne fonctionne pas non plus:
int output = (Func<int, int>)((input) => { return 1; })(0);
donne la même erreur, et pour les raisons mentionnées ci-dessous, je voudrais éviter d'avoir à spécifier explicitement le type d'argument d'entrée (le premier int
).
Vous vous demandez probablement pourquoi je veux faire cela, au lieu de simplement intégrer le code directement, par exemple int output = 1;
. La raison est la suivante: j'ai généré une référence pour un service Web SOAP avec svcutil
lequel, en raison des éléments imbriqués, génère des noms de classe extrêmement longs, que j'aimerais éviter d'avoir à taper. Donc au lieu 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()
};
et une CreateAddress(GetOrderResultOrderShipment_OrderShipmentShipment_Address address)
méthode distincte (les vrais noms sont encore plus longs, et j'ai un contrôle très limité sur le formulaire), je voudrais écrire
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()
};
Je sais que je pourrais écrire
Address = sh.ReceiverAddress_Shipment == null ? null : new Address {
Street = sh.ReceiverAddress_Shipment.Address.Street,
...
}
mais même cela (la sh.ReceiverAddress_Shipment.Address
partie) devient très répétitif s'il y a beaucoup de champs. Déclarer un lambda et l'appeler immédiatement serait plus élégant, moins de caractères à écrire.
public T Exec<T>(Func<T> func) => return func();
et l'utiliser comme ceci: int x = Exec(() => { return 1; });
Cela me semble beaucoup plus agréable que le casting avec toutes ses parens.
int output = ((Func<int>) (() => { return 1; }))();