我正在为属性生成动态代理。在虚拟方法上使用OpCodes.Call是否安全?
生成的代理来自我们想要代理的类型。 当代理需要访问从其派生而来的类型的(虚拟)属性时,不能使用OpCodes.Callvirt
- 它会导致无限递归。因此我们需要拨打OpCodes.Call
。我注意到,如果我有:
public class MyParent
{
protected string _name;
protected string _color;
public virtual string Name
{
get { return _name; }
set { _name = value; }
}
public virtual string Color
{
get { return _color; }
set { _color = value; }
}
}
public class MyChild : MyParent
{
public override string Name {
get { return "42"; }
set { _name = value; }
}
}
当我发出OpCodes.Call
从MyChild
导出的代理对象上调用get_Color
它被正确调用,即使在技术上这种方法是不是MyChild
实现。
我会写一些代码,遍历类型层次到MyParent
其中get_Color
实现可以被发现和使用该类型的方法为OpCodes.Call
,但现在看来,这是没有必要的:
var thisTypeMethod = property.GetGetMethod();
// I know that the next line technically is not correct because of non-virtual methods
// and also *new* overrides. Assume I'm doing it correctly, not by property.Name
// but by repeatedly calling MethodInfo.GetBaseDefinition()
var declaringTypeMethod = property.DeclaringType.GetProperty(property.Name).GetGetMethod();
,然后
var proxyMethod = new DynamicMethod(thisTypeMethod.Name,thisTypeMethod.ReturnType, new Type[]{type},type,true);
var il = proxyMethod.GetILGenerator();
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Tailcall);
il.Emit(OpCodes.Call, thisTypeMethod);
il.Emit(OpCodes.Ret);
它是否安全不使用declaringTypeMethod并使用thisTypeMethod来代替?