2009-07-15 9 views
7

Czy to zadziała jako Expression<Func<T>> lub Func<T> jako klucze w słowniku? Na przykład, aby buforować wynik ciężkich obliczeń.C#: Czy można używać wyrażeń lub funkcji jako klawiszy w słowniku?

Na przykład, zmieniając moje bardzo podstawowy cache z different question kopalni trochę:

public static class Cache<T> 
{ 
    // Alternatively using Expression<Func<T>> instead 
    private static Dictionary<Func<T>, T> cache; 
    static Cache() 
    { 
     cache = new Dictionary<Func<T>, T>(); 
    } 
    public static T GetResult(Func<T> f) 
    { 
     if (cache.ContainsKey(f)) 
      return cache[f]; 

     return cache[f] = f(); 
    } 
} 

Czy to jeszcze działa?

Edytuj: Po szybkim teście wygląda na to, że faktycznie działa. Ale odkryłem, że może to prawdopodobnie bardziej uniwersalne, ponieważ byłoby to teraz jeden cache od rodzaju powrotną ... nie wiem, jak zmienić go tak, by się nie stało, choć ... hmm

Edycja 2 : Noo, czekaj ... w rzeczywistości tak nie jest. Cóż, dla zwykłych metod to robi. Ale nie dla lambd. Otrzymują różne losowe nazwy metod, nawet jeśli wyglądają tak samo. Oh well c”)

+2

Dlaczego to robisz? –

+0

Nie jestem. Po prostu natknąłem się na tę myśl, gdy zastanawiałem się nad sprawami z pamięci podręcznej w moim drugim pytaniu i byłem ciekawy :) – Svish

+0

Punkty bonusowe za ciekawość badawczą, ale nie widzę prawdziwego zastosowania tej techniki. Z drugiej strony pomysł ma wysoki współczynnik chłodzenia, gdyby zadziałał. –

Odpowiedz

3

Można stosować dowolny typ obiektu, o ile jest to przypadek. To nawet będąc delegatem, ale robię nie zalecamy używanie delegatów jak klucze, ponieważ nie są one przeznaczone do Nie jestem pewien, czy niezależnie stworzeni delegaci produkują ten sam kod skrótu, jeszcze mniej, jeśli można je porównać (zrównoważyć):

+0

Wygląda na to, że masz rację co do tego, że delegaci nie pracują dobrze dla kluczy =/ – Svish

+0

Delegaci porównują przez odniesienie, a nie "strukturalnie". Oznacza to, że dwóch delegatów, którzy nazywają ten sam kod, ale są różne instancje będą porównywać jako nierówne. –

+0

@Eric Lippert: Pomyślałem, że jest to naturalny mechanizm awaryjny, gdy "struktura" porównuje się bez znaczenia :) –

0

Może to być odcinek, ale za pomocą języka Dynamic Language Runtime (IronPython itp.) może definitywnie uruchomić dowolne fragmenty kodu ze słownika:

Następnie można uruchomić kod w locie w razie potrzeby, buforować wynik po raz pierwszy, d użyj wyniku z pamięci podręcznej dla wszystkich przyszłych połączeń.

Jeśli miałeś wiele obliczeń, założę się, że to całkiem dobrze. To wszystko jest sytuacyjne i nie jestem pewien, co dokładnie chcesz osiągnąć. :)