문제

함수를 매개변수로 전달할 수 있는 제네릭을 만들고 싶지만 이 함수에는 매개변수 자체가 포함될 수 있으므로...

int foo = GetCachedValue("LastFoo", methodToGetFoo)

다음과 같습니다:

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

기본적으로 캐시에서 값을 확인하는 메서드를 갖고 싶습니다. 그렇지 않으면 전달된 메서드를 기반으로 값을 생성합니다.

생각?

도움이 되었습니까?

해결책

당신이 원하는 것 같네요 Func<T>:

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

그런 다음 발신자는 여러 가지 방법으로 이것을 포장 할 수 있습니다. 간단한 기능 :

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

또는 논증이 관련된 곳, 폐쇄 :

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

다른 팁

System.action 및 Lambda 표현 사용 (anonimous 방법). 예를 들어

    public void myMethod(int integer){

    //Do something

}

public void passFunction(System.Action methodWithParameters){

    //Invoke
    methodWithParameters();

}

//...

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

자신만의 대리자를 만들 수 있지만 C# 3.0에서는 기본 제공되는 대리자를 사용하는 것이 더 편리할 수 있습니다. Func<T> 이 문제를 해결하기 위해 가족을 위임하십시오.예:

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
}

이 메서드는 세 가지 인수를 사용합니다.문자열, int 및 DateTime을 사용하여 int를 반환하는 함수입니다.예를 들어:

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

다른 Func<T, U, V...> 등.다양한 양의 인수를 가진 메소드를 수용하기 위해 프레임워크에 유형이 존재합니다.

방법에 대한 대의원을 만듭니다 methodToGetFoo

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

getCachedValue를 정의하여 대의원을 사용하십시오

int GetCachedValue(string key, GenerateValue functionToCall);

그런 다음 OnGenerateValue를 구현하면 Param을 확인할 수 있습니다.

여기 내가 상업 프로젝트를 위해했던 것처럼 조금 더 나아갈 수있는 간단한 것입니다.

필자의 경우 이것은 웹 서비스 호출을 캐시하는 것이며 다음과 같은 것을 사용했습니다.

WebService ws = new WebService();
var result = ws.Call( x => x.Foo("bar", 1));  // x is the ws instance
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top