2017-03-14 2 views
0

사용자 지정 매개 변수의 사용자 지정 양을 가진 나중에 사용하기 위해 변수에 저장할 수있는 대리자가 필요합니다. 제가 의미하는 바는, 다른 리턴 타입과 다른 인자를 가진 다른 메소드를 푸시하고 싶다는 것입니다. 예를 들어 :어떤 금액의 사용자 지정 매개 변수가있는 대리자

public double Sum (double a, double b) {return a + b;} 
public char GetFirst (string a) {return a[0];} 
public bool canFlipTable (object[] thingsOnIt) {return thingsOnIt.Length <= 3;} 

DoTheThing<double> thing1 = new DoTheThing<double>(Sum); 
DoTheThing<char> thing2 = new DoTheThing<char>(GetFirst); 
DoTheThing<bool> thing3 = new DoTheThing<bool>(canFlipTable); 

thing1.Call(10.3, 5.6); //15.9 
thing2.Call("Hello World"); //'H' 
thing3.Call(new object[] {new Lamp(), new Laptop(), new CoffeMug()}); //true 

내가 반환 값과 이미 호출 방법을 생각,하지만 난 방법

내가 사용하는 경우

을 저장에 문제가있어 "공공 DoTheThing (작업 방법)"가 말한다 , 인수가 나는도했다 대리자 시도 일치하지 않음을 인수로 "[] P 객체 PARAMS"하지만 작동하지 않았다

중 하나 편집 : 는 내가 말할 것을 잊었다, 방법은 항상 WILL 반환 유형 및 최소 1 개의 매개 변수가 있습니다

EDIT 2 : 내 목표는 매우 값 비싼 메서드의 출력을 캐시하는 래퍼 클래스를 만드는 것이고 동일한 것이 다시 호출되면 캐시 된 값을 반환합니다. 물론 인터페이스로이를 해결할 수는 있지만 간단히 편집 할 수없는 클래스를 사용하여이 작업을 수행하려고합니다. 따라서이 메서드를 호출하는 동일한 위치에 캐시를 두는 것이 좋습니다. 어느 쪽인가의 옵션. SOFAR

내 코드 :

public class DoTheThing <T> 
{ 
    public delegate T Method(params object[] parameters); 

    Func<T> method; 
    ParameterInfo[] pInfo; 

    public DoTheThing (Method method) 
    { 
     this.method = method; 
     Type type = typeof(Method); 
     MethodInfo info = type.GetMethod ("Invoke"); 
     if (info.ReturnType != typeof(T)) { 
      throw new Exception ("Type of DoTheThing and method don't match"); 
     } 
     pInfo = info.GetParameters(); 
    } 

    public T Call (params object[] parameters) { 
     if (parameters.Length != pInfo.Length) { 
      throw new Exception ("Wrong number of arguments, " + parameters.Length + " instead of " + pInfo.Length); 
      return default(T); 
     } 

     for (int i = 0; i < parameters.Length; i++) { 
      if (pInfo[i].ParameterType != parameters[i].GetType()) { 
       throw new Exception ("Wrong parameter: " + parameters [i].GetType() + " instead of " + pInfo [i].ParameterType + " at position: " + i); 
       return default(T); 
      } 
     } 

     return (T)method.DynamicInvoke (parameters); 
    } 
} 
+0

DoTheThing (Func 메서드)으로 시도 했습니까? – StfBln

+0

매개 변수가없는 대리자 (someMethod())이기 때문에 여전히 오류가 반환됩니다. – GorbitGames

+0

DoTheThing 코드를 제공하여 모두 동일한 페이지에 있는지 확인하십시오. – StfBln

답변

1

을 수행하는 방법을 파악하는 것을 시도하기 전에, 내가 정말 대리인의 이러한 종류를 가지고 인도하는 문제에 의문을 제기한다. 컨텍스트를 더 잘 알고 있다면 요구 사항을 제거하는 솔루션이있을 것입니다.

그렇다고해서 대리자는 MulticastDelegate에서 상속 한 클래스입니다. 사실 대리자를 선언하면 MulticastDelegate를 기본 클래스로 사용하여 새 클래스 유형을 만듭니다. 즉, 다음과 같은 코드가 작동을 의미합니다

public static double Sum(double a, double b) 
    { 
     return a + b; 
    } 

    public static string SayHello() 
    { 
     return "Hello"; 
    } 

    static void Main(string[] args) 
    { 
     MulticastDelegate mydel = new Func<double, double, double>(Sum); 
     var ret = mydel.DynamicInvoke(1, 2); 
     System.Console.WriteLine(ret); 

     mydel = new Func<string>(SayHello); 
     ret = mydel.DynamicInvoke(); 
     System.Console.WriteLine(ret); 


     mydel = new Func<string, int, string> ((s, i) => { 
      return $"Would be {s}, {i} times"; 
     }); 
     ret = mydel.DynamicInvoke("Hello", 5); 
     System.Console.WriteLine(ret); 
    } 

때문에 "MYDEL"변수는 기본 클래스 유형 (MulticastDelegate), 우리가 실제로 위임 어떤 종류를 사용하고 임의의 매개 변수를 호출 할 수 있습니다입니다. 호출되는 메소드와 일치하지 않으면 런타임에 throw됩니다.