2008-10-01 11 views
9

Napisałem prostą klasę zarządzania SessionItem, aby obsłużyć wszystkie te nieznane sprawdzenia zerowe i wstawić domyślną wartość, jeśli żadna nie istnieje. Oto moja metoda GetItem:C# - Jak zdefiniować metodę inline Func <T> jako parametr?

public static T GetItem<T>(string key, Func<T> defaultValue) 
{ 
    if (HttpContext.Current.Session[key] == null) 
    { 
     HttpContext.Current.Session[key] = defaultValue.Invoke(); 
    } 
    return (T)HttpContext.Current.Session[key]; 
} 

Teraz, jak mam właściwie to wykorzystać, przechodzącą w Func <T> jako metoda parametru inline?

Odpowiedz

16

Ponieważ jest to func, lambda byłoby najprostszym sposobem:

Foo foo = GetItem<Foo>("abc",() => new Foo("blah")); 

gdzie [new Foo ("bla")] jest func, który jest wywoływany jako domyślny.

Można również uprościć do:

return ((T)HttpContext.Current.Session[key]) ?? defaultValue(); 

Gdzie ?? jest operatorem koalescencyjnym - jeśli pierwszy argument nie ma wartości NULL, jest zwracany; w przeciwnym razie prawa ręka jest oceniana i zwracana (więc defaultValue() nie jest wywoływana, chyba że element jest pusty).

Wreszcie, jeśli chcesz po prostu użyć konstruktora domyślnego, a następnie można dodać „new()” ograniczenie:

public static T GetItem<T>(string key) 
    where T : new() 
{ 
    return ((T)HttpContext.Current.Session[key]) ?? new T(); 
} 

To wciąż leniwy - nowy() jest używana tylko wtedy, gdy pozycja był zerowy.

+2

The ?? wersja nie ustawia wartości w sesji. –

2

Dlaczego nie przekazujesz wartości domyślnej bezpośrednio? Jaki jest pożytek z funktora?

Przy okazji, defaultValue.Invoke() jest dość gadatliwy. Możliwe jest również napisanie defaultValue().

+0

Chyba chce wartość domyślną do oceny tylko w razie potrzeby, np jeśli wartość domyślna jest kosztowna do obliczenia. – OregonGhost

+1

Jeśli przekazuję wartość domyślną bezpośrednio, to jeśli domyślną instancją jest nowa instancja obiektu, będę tworzył ten domyślny obiekt za każdym razem, gdy wołam GetItem, niezależnie od tego, czy będzie on używany, czy nie. Wstawienie do Func odrzuca instancję tylko wtedy, gdy jest potrzebna. – tags2k

+1

Jeśli masz do czynienia z instancją i jeśli korzystasz z domyślnego konstruktora - wtedy pomocne może być ogólne ograniczenie ": new()" (zmieniłem swój post, aby dołączyć). Podejście Func jest przydatne, jeśli używasz innego niż domyślny konstruktora. –

1
var log = SessionItem.GetItem("logger",() => NullLog.Instance) 

Uwaga, niż normalnie można pominąć {T} specyfikacja w GetItem {T} rozmowy (Jeśli func {T} zwraca obiekt tego samego typu)

Powiązane problemy