Frage

Ich möchte eine generisch zu schaffen, an dem ich eine Funktion als Parameter übergeben kann, jedoch kann diese Funktion Parameter umfassen selbst so ...

int foo = GetCachedValue("LastFoo", methodToGetFoo)

So, dass:

protected int methodToGetFoo(DateTime today)
{ return 2; // example only }

Im Grunde möchte ich eine Methode haben, die den Cache auf einen Wert geprüft werden, andernfalls wird der Wert erzeugen auf der Basis der in-Methode übergeben.

Die Gedanken?

War es hilfreich?

Lösung

Es klingt wie Sie eine Func<T> wollen:

T GetCachedValue<T>(string key, Func<T> method) {
     T value;
     if(!cache.TryGetValue(key, out value)) {
         value = method();
         cache[key] = value;
     }
     return value;
}

Der Anrufer kann dann diese wickelt in vielerlei Hinsicht; für einfache Funktionen:

int i = GetCachedValue("Foo", GetNextValue);
...
int GetNextValue() {...}

oder wo Argumente beteiligt sind, eine Schließung:

var bar = ...
int i = GetCachedValue("Foo", () => GetNextValue(bar));

Andere Tipps

Mit System.Action und Lambda-Ausdruck (anonimous Methode). Zum Beispiel

    public void myMethod(int integer){

    //Do something

}

public void passFunction(System.Action methodWithParameters){

    //Invoke
    methodWithParameters();

}

//...

//Pass anonimous method using lambda expression
passFunction(() => myMethod(1234));

Sie können Ihren eigenen Delegierten, aber in C # 3.0 erstellen Sie finden es bequemer, die sich im internen Func<T> delegieren Familie zu lösen dieses Problem zu verwenden. Beispiel:

public int GetCachedValue(string p1, int p2,
                          Func<DateTime, int> getCachedValue)
{
    // do some stuff in here
    // you can call getCachedValue like any normal function from within here
}

Diese Methode drei Argumente: ein String, ein int, und eine Funktion, die eine Datetime nimmt ab und gibt einen int. Zum Beispiel:

int foo = GetCachedValue("blah", 5, methodToGetFoo);   // using your method
int bar = GetCachedValue("fuzz", 1, d => d.TotalDays); // using a lambda

Verschiedene Func<T, U, V...> usw. Typen existieren im Rahmen Methoden mit unterschiedlichen Mengen von Argumenten gerecht zu werden.

Erstellen Sie einen Delegaten für die Methode methodToGetFoo

public delegate object GenerateValue(params p);
public event GenerateValue OnGenerateValue;

definieren GetCachedValue die Delegaten verwenden

int GetCachedValue(string key, GenerateValue functionToCall);

Dann bei der Umsetzung der OnGenerateValue können Sie den param der überprüfen.

Hier ist ich etwas einfach gestartet das kann ein bisschen weiter genommen werden (wie ich für ein kommerzielles Projekt tat).

In meinem Fall war die Web-Service-Aufruf cachen, und wurde so etwas wie verwendet:

WebService ws = new WebService();
var result = ws.Call( x => x.Foo("bar", 1));  // x is the ws instance
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top