动态地获得被覆盖的属性值 [英] Dynamically get value from overriden property

查看:102
本文介绍了动态地获得被覆盖的属性值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想能够使用反射在运行时动态地得到一个被覆盖的属性的值。例如,

  A级{
公共虚拟INT美孚=> 5;

//此实现不起作用
公众诠释ParentFoo => (INT)this.GetType()BaseType.GetProperty(nameof(美孚))的GetValue(本)。
}

B类:A {
公共覆盖INT美孚=> 7;
}

变种测试=新B();
Console.WriteLine(test.Foo); //7
Console.WriteLine(test.ParentFoo); //应该显示5



这样做的一点是,类型层次是相当深,我不想扩展不得不重新实现 ParentFoo 每次用完全相同的逻辑(公众诠释ParentFoo => base.Foo; )。我不介意多付的性能成本这个反射现象的物业并不需要是高性能的。



是否有可能完成什么,我需要在这里使用反射<? / p>

解决方案

有可能随时拨打原来的定义类的使用反射特性的方法。这是一个坏主意。下面的代码说明了这一概念,但没有战值得,不应该进行的战斗值得。

 无效的主要() 
{
VAR一个=新的A();
Console.WriteLine(GetNoVCall< A,INT>(A,Z => z.Foo)); //输出5
变种B =新的B();
Console.WriteLine(GetNoVCall< A,INT>(B,Z => z.Foo)); //输出5
Console.WriteLine(GetNoVCall< B,INT>(B,Z => z.Foo)); //输出5
}

等级A
{
公共虚拟INT美孚{{返回5; }}
}

B类:A
{
公众覆盖INT美孚{{返回7; }}
}

公共静态TProp GetNoVCall< TClass,TProp>(TClass C,表达式来; Func键< TClass,TProp>> F)
{
变种EXPR = f.Body为MemberExpression;
VAR道具= expr.Member为的PropertyInfo;
变种甲= prop.GetGetMethod(真);
变种SRC = expr.Expression为ParameterExpression;

如果(SRC == NULL ||道具== NULL || EXPR == NULL)
抛出新的异常();

变种DYN =新的DynamicMethod的(GetNoVCallHelper的typeof(TProp),新类型[] {typeof运算(TClass)},typeof运算(字符串).Module,真正的);
变种IL = dyn.GetILGenerator();
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Call,甲基);
il.Emit(OpCodes.Ret);

回报率((Func键< TClass,TProp>)dyn.CreateDelegate(typeof运算(Func键< TClass,TProp>)))(C);
}


I would like to be able to dynamically get the value of an overriden property at runtime using reflection. For example,

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"

The point of doing this is that the type hierarchy is fairly deep and I don't want extenders to have to re-implement ParentFoo each time with the exact same logic (public int ParentFoo => base.Foo;). I don't mind paying the performance cost for reflection- this property doesn't need to be performant.

Is it possible to accomplish what I need here using reflection?

解决方案

It is possible to always call the original defining class's method for the property using reflection. This is a bad idea. The following code illustrates the concept but isn't battle worthy, and shouldn't be made battle worthy.

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);
}

这篇关于动态地获得被覆盖的属性值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆