2011-04-20 4 views
4

다음 내 코드가 될 때 : 그것은 말을 나에게 오류를주고있다위임 오류가

class PropertyRetrievalClass 
{ 
    public delegate object getProperty(string input); 

    public object get_Chart_1(string iput) 
    { 
     Console.WriteLine(iput); 
     return ""; 
    } 
    public object get_Chart_2(string iput) 
    { 
     Console.WriteLine(iput); 
     return ""; 
    } 

    public PropertyRetrievalClass() { } 
} 

public static void Main() 
     { 
      int i = 1; 
      PropertyRetrievalClass obj = new PropertyRetrievalClass(); 

      Delegate del = Delegate.CreateDelegate(typeof(PropertyRetrievalClass), obj, "get_chart_" + i.ToString()); 
      string output= del("asldkl"); 
     } 

"오류 CS0118 : '델'는 '변수'이지만 '방법'처럼 사용된다"

이 위임자를 사용하려면 어떻게해야합니까? "get_chart_1"또는 "get_chart_2"함수 중 하나를 호출하고 둘 다 문자열 입력을 원합니다? 당신은 Delegate유형의 메소드를 호출 할 수 없습니다

답변

3

코드에 두 가지 문제가 있습니다.

  • Delegate 객체가 방법이 아닙니다, 그래서 당신이 그것을 참조하는 방법을 호출 할 Delegate 객체의 메소드를 사용할 필요가
  • CreateDelegate에 첫 번째 인수는 대리자 형식이 아닌를 포함하는 클래스해야한다 메소드를 호출 할 수 있습니다.

전체 작업 예 :

귀하의 경우
public delegate void ParamLess(); 
class SomeClass 
{ 
    public void PrintStuff() 
    { 
     Console.WriteLine("stuff"); 
    } 
} 
internal class Program 
{ 
    private static Dictionary<int, int> dict = null; 
    static void Main() 
    { 
     var obj = new SomeClass(); 
     Delegate del = Delegate.CreateDelegate(typeof(ParamLess), obj, 
       "PrintStuff", false); 
     del.DynamicInvoke(); // invokes SomeClass.PrintStuff, which prints "stuff" 
    } 
} 

Main 방법은 다음과 같아야합니다 CreateDelegate이 방법에 대소 문자를 구분
하는 것으로

public static void Main() 
{ 
    int i = 1; 
    PropertyRetrievalClass obj = new PropertyRetrievalClass(); 

    Delegate del = Delegate.CreateDelegate(
     typeof(PropertyRetrievalClass.getProperty), 
     obj, 
     "get_Chart_" + i.ToString()); 
    string output = (string)del.DynamicInvoke("asldkl"); 
} 

업데이트 당신이 말하지 않는 한, 이름.

// this call will fail, get_chart should be get_Chart 
Delegate del = Delegate.CreateDelegate(
     typeof(PropertyRetrievalClass.getProperty), 
     obj, 
     "get_chart_" + i.ToString()); 


// this call will succeed 
Delegate del = Delegate.CreateDelegate(
     typeof(PropertyRetrievalClass.getProperty), 
     obj, 
     "get_Chart_" + i.ToString()); 


// this call will succeed, since we tell CreateDelegate to ignore case 
Delegate del = Delegate.CreateDelegate(
     typeof(PropertyRetrievalClass.getProperty), 
     obj, 
     "get_chart_" + i.ToString(), 
     true); 
+0

예외가 발생했습니다 : 대상 메서드에 대한 바인딩 오류 :-( – seoul

+0

@seoul : 대답의 업데이트를 참조하십시오. –

+0

감사합니다. 유용한 답변 :-) 감사합니다 ... – seoul

0

사전에

감사합니다 .... 매우 slowwwwwwwDynamicInvoke()을 사용해야합니다.

이 시도 : 당신은 Delegate 클래스가 아닌 delegate 키워드를 사용하는

string output = (string) del.DynamicInvoke(new object[]{"asldkl"}); 
0

.

0

알려진 서명이있는 경우에만 메서드 호출 구문을 사용하여 대리자를 호출 할 수 있습니다. 위의 정의 된 대리자 형식으로 대리인을 캐스팅해야합니다. 는 대리자 형식해야하기 때문에

var del = (PropertyRetrievalClass.getProperty)Delegate.CreateDelegate(typeof(PropertyRetrievalClass.getProperty), obj, "get_Chart_" + i.ToString()); 

는 또한, CreateDelegate에 첫 번째 인수를 변경해야합니다. 그리고 "get_Chart_"에서 "C"를 대문자로 만드십시오.

string output= (string) del("asldkl"); 

을하거나 반환 형식으로 string을 위해 대리자 형식과 방법을 변경

그리고, 당신은 반환 objectstring에 캐스팅해야합니다.

+1

getProperty는 Main에 표시되지 않습니다. 이렇게 편집 됨 -> PropertyRetrievalClass.getProperty del = (PropertyRetrievalClass.getProperty) Delegate.CreateDelegate (typeof (PropertyRetrievalClass), obj, "get_chart_"+ i.ToString()); 문자열 출력 = new del ("asldkl"); ************* 작동하지 않습니다 ...이 오류 -> 유형 또는 네임 스페이스 이름 'del'을 (를) 찾을 수 없습니다. using) – seoul

1

다른 답변으로 코드 문제가 해결되었지만 대안을 제시하고자했습니다.이 있다면

public int MethodIndex {get;set;} 
public static void Main() 
{ 
    PropertyRetrievalClass obj = new PropertyRetrievalClass(); 
    Func<string,object> getChartMethod; 
    switch(MethodIndex) 
    { 
     case 1: 
      getChartMethod = obj.get_chart_1; 
      break; 
     case 2: 
      getChartMethod = obj.get_chart_2; 
      break; 
    }    
    string output= getChartMethod("asldkl"); 
} 

: 거기 검색 클래스에서 선택되는 방법의 제한, 유한 수 있으며, 그들은이 같은 서명이있는 경우

,이 반사를 사용하지 않고 훨씬 더 효율적으로 수행 할 수 있습니다 스위치를 사용하는 대신 배열을 만들 수 있습니다. 당연히 스위치에서 직접 적절한 함수를 실행할 수는 있지만 위임자를 호출자에게 다시 전달하려는 생각이 있다고 가정합니다. 이렇게 생성하면 리플렉션을 사용하지 않고도 수행 할 수 있습니다.

public static Func<string,object> GetMethod 
{ 
... just return getChartMethod directly 
} 
+0

yah ... 너의 해결책 일 수도있다. 또한 대의원 만 사용하도록 강요받지 않는다면. – seoul

+0

+1 또한 귀하의 아이디어입니다. – seoul