从overriden属性动态获取值
本文关键字:获取 动态 属性 overriden | 更新日期: 2023-09-27 18:23:36
我希望能够在运行时使用反射动态获取overriden属性的值。例如,
class A {
public virtual int Foo => 5;
//This implementation doesn't work
public int ParentFoo => (int)this.GetType().BaseType.GetProperty(nameof(Foo)).GetValue(this);
}
class B : A {
public override int Foo => 7;
}
var test = new B();
Console.WriteLine(test.Foo); //"7"
Console.WriteLine(test.ParentFoo); //Should display "5"
这样做的目的是类型层次结构相当深,我不希望扩展程序每次都必须用完全相同的逻辑(public int ParentFoo => base.Foo;
)重新实现ParentFoo
。我不介意为反思支付性能成本——这处房产不需要具有性能。
有可能用反射来完成我在这里需要的东西吗?
可以始终使用反射为属性调用原始定义类的方法。这是个坏主意。下面的代码说明了这个概念,但不值得战斗,也不应该让它成为值得战斗的代码。
void Main()
{
var a = new A();
Console.WriteLine(GetNoVCall<A, int>(a, z => z.Foo)); // prints 5
var b = new B();
Console.WriteLine(GetNoVCall<A, int>(b, z => z.Foo)); // prints 5
Console.WriteLine(GetNoVCall<B, int>(b, z => z.Foo)); // prints 5
}
class A
{
public virtual int Foo { get { return 5; } }
}
class B : A
{
public override int Foo { get { return 7; } }
}
public static TProp GetNoVCall<TClass, TProp>(TClass c, Expression<Func<TClass, TProp>> f)
{
var expr = f.Body as MemberExpression;
var prop = expr.Member as PropertyInfo;
var meth = prop.GetGetMethod(true);
var src = expr.Expression as ParameterExpression;
if (src == null || prop == null || expr == null)
throw new Exception();
var dyn = new DynamicMethod("GetNoVCallHelper", typeof(TProp), new Type[]{ typeof(TClass) }, typeof(string).Module, true);
var il = dyn.GetILGenerator();
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Call, meth);
il.Emit(OpCodes.Ret);
return ((Func<TClass, TProp>)dyn.CreateDelegate(typeof(Func<TClass, TProp>)))(c);
}