È possibile dichiarare una funzione lambda e chiamarla immediatamente:
Func<int, int> lambda = (input) => { return 1; };
int output = lambda(0);
Mi chiedo se sia possibile farlo in una riga, ad esempio qualcosa del genere
int output = (input) => { return 1; }(0);
che fornisce un errore del compilatore "Nome metodo previsto". Casting Func<int, int>
non funziona neanche:
int output = (Func<int, int>)((input) => { return 1; })(0);
fornisce lo stesso errore e per i motivi indicati di seguito vorrei evitare di specificare esplicitamente il tipo di argomento di input (il primo int
).
Probabilmente ti starai chiedendo perché voglio farlo, invece di incorporare direttamente il codice, ad es int output = 1;
. Il motivo è il seguente: ho generato un riferimento per un servizio web SOAP con svcutil
, che a causa degli elementi nidificati genera nomi di classe estremamente lunghi, che vorrei evitare di dover digitare. Quindi invece di
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()
};
e un CreateAddress(GetOrderResultOrderShipment_OrderShipmentShipment_Address address)
metodo separato (i nomi reali sono ancora più lunghi e ho un controllo molto limitato sul modulo), mi piacerebbe scrivere
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()
};
So di poter scrivere
Address = sh.ReceiverAddress_Shipment == null ? null : new Address {
Street = sh.ReceiverAddress_Shipment.Address.Street,
...
}
ma anche quello (la sh.ReceiverAddress_Shipment.Address
parte) diventa molto ripetitivo se ci sono molti campi. Dichiarare un lambda e chiamarlo immediatamente sarebbe più elegante meno personaggi da scrivere.
public T Exec<T>(Func<T> func) => return func();
e usarlo in questo modo: int x = Exec(() => { return 1; });
per me è molto più bello del casting con tutte le sue parentesi.
int output = ((Func<int>) (() => { return 1; }))();