2013-10-23 4 views
3

나는이 같은 질문이 이미 있다는 것을 알고 있지만, 나는 심각하게 대답을 이해하지 못한다 (그리고 나는 그것에 대해 논평 할 수 없다).리플렉션을 통해 얻은 메서드를 대리자에게 할당하는 방법은 무엇입니까? (또는 : 리플렉션을 통해 메서드 호출의 속도를 높이는 방법)

나는 완전히 새로운 리플렉션이고, 새로운 델리게이트도 새롭다. 그래서 이것은 나에게 상당히 어렵다.

A는 얼마 전 나는 (간체) 이런 식으로했다, 방법을 얻기 위해 (처음으로) 반사를 사용 :

object perlinObj; 
MethodInfo PerlinMethod = null;  
//... 
ConstructorInfo constructor = type.GetConstructor(Type.EmptyTypes); 
perlinObj = constructor.Invoke(new object[] { }); 
PerlinMethod = type.GetMethod("GetValue", new Type[] { typeof(Vector3) }); 
//... 
float PerlinFunction(Vector3 pos) 
{ 
    return (float)((Double)PerlinMethod.Invoke(perlinObj, new object[] { pos })); 
} 

이 작동하지만 문제는이보다 훨씬 느린 점입니다 메소드를 직접 호출하면됩니다. 그래서 어쨌든 대리인에게 할당 한 다음 invoke를 사용하는 대신 위임자를 호출하는 것이 좋을 것이라고 생각했습니다. (맞습니까?)

하지만 어떻게하는지는 알 수 없습니다. msdn : http://msdn.microsoft.com/en-us/library/ms228976.aspx에 대한 설명서를 이해하지 못합니다. (내가 수행하려고 시도하는 것과 동일하지는 않습니다.) Assign method to delegate through reflection을 정확히 읽어야합니다.

(그리고 내가 작동하지 않았다 시도)

그래서 누군가가 나에게 설명 할 수있는 내가 제공된 예제 코드에서해야 할?

답변

3

"쉬운"방법을 수행하려면 object보다 정확하게 대상을 알아야합니다. 당신이 필요

object perlinObj; 

: 즉, 대신

SomeType perlinObj; 

을 그리고, 우리가 대리자를 만들기 위해 Delegate.CreateDelegate를 사용하는 대신 MethodInfo를 저장하는 - 나는 Vector3의 장소에 여기 int을 사용하고 있습니다 내 편의 :

Func<SomeType, int, float> PerlinMethod; 
//... 
PerlinMethod = (Func<SomeType, int, float>) Delegate.CreateDelegate(
     typeof(Func<SomeType, int, float>), 
     null, 
     type.GetMethod("GetValue", new Type[] { typeof(int) })); 
//... 
float PerlinFunction(int pos) 
{ 
    return PerlinMethod(perlinObj, pos); 
} 

대상 인스턴스가 절대로 변경되지 않으면 다음을 단순화 할 수 있습니다.

Func<int, float> PerlinMethod; 
//... 
PerlinMethod = (Func<int, float>) Delegate.CreateDelegate(
     typeof(Func<int, float>), 
     perlinObj, 
     type.GetMethod("GetValue", new Type[] { typeof(int) })); 
//... 
float PerlinFunction(int pos) 
{ 
    return PerlinMethod(pos); 
} 

그렇게 할 수 없다면보다 발전된 메타 프로그래밍을 사용해야 할 것입니다. ILGenerator 또는 Expression :

Func<object, int, float> PerlinMethod; 
//... 
var target = Expression.Parameter(typeof(object)); 
var arg = Expression.Parameter(typeof(int)); 
var call = Expression.Call(
    Expression.Convert(target, type), 
    type.GetMethod("GetValue", new Type[] { typeof(int) }), 
    arg); 

PerlinMethod = Expression.Lambda<Func<object,int,float>>(
    call, target, arg).Compile(); 
+0

아니요, 제 잘못입니다. 도움 주셔서 감사합니다. – Stef