기본 클래스의 이벤트 핸들러를 호출하는 MSIL은 무엇입니까?
-
06-07-2019 - |
문제
EventConsumer라는 클래스가 있습니다. 이벤트는 이벤트 소비와 다음과 같이 oneventConsumed 메소드를 정의합니다.
public event EventHandler EventConsumed;
public virtual void OnEventConsumed(object sender, EventArgs e)
{
if (EventConsumed != null)
EventConsumed(this, e);
}
AT OneventConsumed 런타임에 속성을 추가해야하므로 System.Reflection.emit을 사용하여 서브 클래스를 생성합니다. 내가 원하는 것은 이것과 동등한 MSIL입니다.
public override void OnEventConsumed(object sender, EventArgs e)
{
base.OnEventConsumed(sender, e);
}
내가 지금까지 가지고있는 것은 다음과 같습니다.
...
MethodInfo baseMethod = typeof(EventConsumer).GetMethod("OnEventConsumed");
MethodBuilder methodBuilder = typeBuilder.DefineMethod("OnEventConsumed",
baseMethod.Attributes,
baseMethod.CallingConvention,
typeof(void),
new Type[] {typeof(object),
typeof(EventArgs)});
ILGenerator ilGenerator = methodBuilder.GetILGenerator();
// load the first two args onto the stack
ilGenerator.Emit(OpCodes.Ldarg_1);
ilGenerator.Emit(OpCodes.Ldarg_2);
// call the base method
ilGenerator.EmitCall(OpCodes.Callvirt, baseMethod, new Type[0] );
// return
ilGenerator.Emit(OpCodes.Ret);
...
유형을 생성하고 유형의 인스턴스를 만들고 OneventConsumed 함수를 호출하면 다음을 얻습니다.
Common Language Runtime detected an invalid program.
... 정확히 도움이되지 않습니다. 내가 뭘 잘못하고 있죠? 기본 클래스의 이벤트 핸들러를 호출하는 올바른 MSIL은 무엇입니까?
해결책
다음은 샘플 앱의 IL입니다.
.method public hidebysig virtual instance void OnEventConsumed(object sender, class [mscorlib]System.EventArgs e) cil managed
{
.maxstack 8
L_0000: nop
L_0001: ldarg.0
L_0002: ldarg.1
L_0003: ldarg.2
L_0004: call instance void SubclassSpike.BaseClass::OnEventConsumed(object, class [mscorlib]System.EventArgs)
L_0009: nop
L_000a: ret
}
그래서 나는 당신이 ldarg.0을하지 않기 때문에 인스턴스를로드하지 않는 것 같습니다.
다른 팁
나는 실제로 정말 가까웠다 - 문제는 내가 '이'주장을로드하지 않았다는 것이었다. 그 섹션은 다음과 같이됩니다.
// load 'this' and the first two args onto the stack
ilGenerator.Emit(OpCodes.Ldarg_0);
ilGenerator.Emit(OpCodes.Ldarg_1);
ilGenerator.Emit(OpCodes.Ldarg_2);
// call the base method
ilGenerator.EmitCall(OpCodes.Call, baseMethod, new Type[0] );
// return
ilGenerator.Emit(OpCodes.Ret);
이제 잘 작동합니다.
사용
public virtual void OnEventConsumed(object sender, EventArgs e)
{
if (EventConsumed != null)
EventConsumed(this, e);
}
해야한다
public virtual void OnEventConsumed(EventArgs e)
{
EventHandler handler = this.EventConsumed;
if ( null != handler ) handler( this, e );
}
.
나는 당신은 a를 사용해야한다고 생각합니다 ilgenerator.emitcalli 그리고 당신은 반환 값 유형 (이 경우 null이라고 생각합니다)을 전달하고 인수 유형을 전달해야합니다.
제휴하지 않습니다 StackOverflow