Można zadeklarować funkcję lambda i natychmiast ją wywołać:
Func<int, int> lambda = (input) => { return 1; };
int output = lambda(0);
Zastanawiam się, czy można to zrobić w jednym wierszu, np. Coś takiego
int output = (input) => { return 1; }(0);
co daje błąd kompilatora „Oczekiwana nazwa metody”. Przesyłanie do Func<int, int>
nie działa:
int output = (Func<int, int>)((input) => { return 1; })(0);
daje ten sam błąd iz powodów wymienionych poniżej chciałbym uniknąć konieczności jawnego podawania typu argumentu wejściowego (pierwszy int
).
Prawdopodobnie zastanawiasz się, dlaczego chcę to zrobić, zamiast bezpośrednio osadzać kod, np int output = 1;
. Powód jest następujący: Wygenerowałem odwołanie do usługi internetowej SOAP svcutil
, która ze względu na zagnieżdżone elementy generuje wyjątkowo długie nazwy klas, których nie chciałbym pisać. Więc zamiast
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()
};
i osobna CreateAddress(GetOrderResultOrderShipment_OrderShipmentShipment_Address address)
metoda (prawdziwe nazwy są jeszcze dłuższe, a ja mam bardzo ograniczoną kontrolę nad formularzem), chciałbym pisać
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()
};
Wiem, że mógłbym pisać
Address = sh.ReceiverAddress_Shipment == null ? null : new Address {
Street = sh.ReceiverAddress_Shipment.Address.Street,
...
}
ale nawet to ( sh.ReceiverAddress_Shipment.Address
część) staje się bardzo powtarzalne, jeśli istnieje wiele pól. Zadeklarowanie lambdy i natychmiastowe wywołanie byłoby bardziej eleganckim, mniejszym znakiem do pisania.
public T Exec<T>(Func<T> func) => return func();
i użyj go w ten sposób: int x = Exec(() => { return 1; });
To dla mnie brzmi o wiele ładniej niż casting ze wszystkimi jego częściami.
int output = ((Func<int>) (() => { return 1; }))();