에 나는 같음을 무시 Reflection.Emit를를 사용하여 동적 프록시를 방출하는 데 필요한 다음 클래스 A를Reflection.Emit 코드는 "base"를 호출합니다. "this"대신에. 부울 필드
public class A
{
public string Name { get; set; }
}
있습니다.
// This class must be generated by Reflection.Emit.
public class AProxy : A
{
private bool equalsHasBeenCalled;
public override bool Equals(object obj)
{
if (this.equalsHasBeenCalled)
{
return base.Equals(obj);
}
this.equalsHasBeenCalled = true;
return CaseInsensitiveComparer.Equals(this, obj); // Demo.
}
}
그러나, (본 리플렉터) 실제 발전 코드 : 물론
public class AProxy : A
{
private bool equalsHasBeenCalled;
public override bool Equals(object obj)
{
if (base.equalsHasBeenCalled)
{
return base.Equals(obj);
}
base.equalsHasBeenCalled = true;
return CaseInsensitiveComparer.Equals(this, obj);
}
}
요식는 System.FieldAccessException를 (그러한 부재가 존재하지 않기 때문에) 발생. 올바른 것은 this.equalsHasBeenCalled (base.equalsHasBeenCalled 아님)으로 전화하는 것입니다.
I 추가 기능 반사판에 대한 코드를 생성하기 위해 (필드 1 필드 "equalsHasBeenCalled"는 대한의 fieldInfo 임) Reflection.Emit를 사용하고 있습니다 : 아마도
// Writing body
gen.Emit(OpCodes.Nop);
// I suspect it has to be around here.
gen.Emit(OpCodes.Ldarg_0);
gen.Emit(OpCodes.Ldfld, field1);
gen.Emit(OpCodes.Ldc_I4_0);
gen.Emit(OpCodes.Ceq);
gen.Emit(OpCodes.Stloc_1);
gen.Emit(OpCodes.Ldloc_1);
gen.Emit(OpCodes.Brtrue_S, label25);
gen.Emit(OpCodes.Nop);
gen.Emit(OpCodes.Ldarg_0);
gen.Emit(OpCodes.Ldarg_1);
gen.Emit(OpCodes.Call, method2);
gen.Emit(OpCodes.Stloc_0);
gen.Emit(OpCodes.Br_S, label42);
gen.MarkLabel(label25);
// ..and probably here also?
gen.Emit(OpCodes.Ldarg_0);
gen.Emit(OpCodes.Ldc_I4_1);
gen.Emit(OpCodes.Stfld, field1);
gen.Emit(OpCodes.Ldarg_0);
gen.Emit(OpCodes.Ldarg_1);
gen.Emit(OpCodes.Call, method3);
gen.Emit(OpCodes.Stloc_0);
gen.Emit(OpCodes.Br_S, label42);
gen.MarkLabel(label42);
gen.Emit(OpCodes.Ldloc_0);
gen.Emit(OpCodes.Ret);
그러면이 출력은 어떻게 보입니까? 깨진 decompiler 같은 소리 ... – leppie
Reflection.Emit에 대한 자신의 코드를 보여 주시겠습니까? – leppie
왜 C#에서 필요한 것을 작성하지 않고 IL로 디 컴파일하여 설정 방법을 확인하십시오. 프로젝트에서 이와 같은 작업을 더해야한다면 Castle DynamicProxy를 살펴 보시기 바랍니다. –