Получение значения свойства baseclass с использованием отражения - base.Property, а не this.Property - PullRequest
2 голосов
/ 15 июля 2011

Я хочу знать, возможно ли что-то подобное: я переопределил свойство базового класса, которое реализовано автоматически.Я предоставил логику в переопределении, чтобы разрешить «отсутствующие» свойства по сравнению с настройками по умолчанию.

Теперь я хочу использовать отражение, чтобы проверить, используется ли значение по умолчанию или какое-то «фактическое» значение.Другими словами, мне нужно проверить, является ли base.Property нулевым, но с помощью отражения.Это не работает, оно просто получает значение подкласса (которое разрешается по умолчанию, поэтому не ноль).

var property = this.GetType().GetProperty(e.PropertyName);
if(property.GetValue(this, null) == null))
    OnPropertyChanged(e.PropertyName);

Также пробовал:

var property = this.GetType().BaseType.GetProperty(e.PropertyName);
if(property.GetValue(this, null) == null))
    OnPropertyChanged(e.PropertyName);

Возможно ли этоиспользование отражения для доступа к значению базового класса?

ОБНОВЛЕНИЕ:

Следуя советам из комментариев, я попробовал следующее, только для ударов.

var method1 = this.GetType().BaseType.GetMethods().First(x => x.Name.Contains(e.PropertyName));
var method = this.GetType().BaseType.GetProperty(e.PropertyName).GetGetMethod();
var methodValue = method1.Invoke(this, null);

Оба эти все ещевозвращает «производное» значение, в то же время base.Property возвращает ноль.

Ответы [ 2 ]

5 голосов
/ 16 июля 2011

Это возможно, хотя, насколько я знаю, нет способа сделать это без излучения собственного IL, в основном используя инструкцию call вместо callvirt.

Обратите внимание, что если вам нужно сделать все возможное, чтобы ваш дизайн работал, это признак того, что вы, вероятно, где-то делаете что-то не так!

В любом случае, вот надуманный пример.(Проверка ошибок и т. Д. Для краткости опущена.)

var derived = new DerivedClass();
Console.WriteLine(derived.GetBaseProperty("Prop"));    // displays "BaseProp"

// ...

public class BaseClass
{
    public virtual string Prop { get; set;}
}

public class DerivedClass : BaseClass
{
    public override string Prop { get; set;}

    public DerivedClass()
    {
        base.Prop = "BaseProp";
        this.Prop = "DerivedProp";
    }

    public object GetBaseProperty(string propName)
    {
        Type t = this.GetType();
        MethodInfo mi = t.BaseType.GetProperty(propName).GetGetMethod();

        var dm = new DynamicMethod("getBase_" + propName, typeof(object), new[] { typeof(object) }, t);

        ILGenerator il = dm.GetILGenerator();
        il.Emit(OpCodes.Ldarg_0);
        il.Emit(OpCodes.Call, mi);
        if (mi.ReturnType.IsValueType) il.Emit(OpCodes.Box, mi.ReturnType);
        il.Emit(OpCodes.Ret);

        var getBase = (Func<object, object>)dm.CreateDelegate(typeof(Func<object, object>));
        return getBase(this);
    }
}
1 голос
/ 16 июля 2011

AFAIK Я думаю, что это невозможно.Тип объекта real является производным типом, и по определению virtual методов, независимо от того, через какой экземпляр типа (фактический тип или базовый тип) вы вызываете метод, вы будетеполучить переопределенную реализацию.

Выполнение этой работы любым другим способом было бы, по крайней мере для меня, неожиданным поведением.

РЕДАКТИРОВАТЬ : я попробовал следующее, чтобы увидеть,на самом деле можно добраться до базового внедрения:

Type baseType = this.GetType().BaseType;
var methodInfo = baseType.GetMethod("Foo");
string foo = methodInfo.Invoke(this, null); //Derived type implementation

Это означает, что даже вызов метода через отражение base type MethodInfo способен разрешить переопределение и вернет производную реализацию.Поэтому я думаю, что то, что вы пытаетесь сделать, невозможно с помощью размышлений или, по крайней мере, я не вижу способа сделать это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...