Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting baseclass property value using reflection - base.Property as opposed to this.Property

I want to know if something like this is possible: I've overriden a property of a base class, which is auto-implemented. I've supplied logic in the override to resolve "missing" properties against default settings.

Now, I want to use reflection to check whether the default value is used or some "actual" value. In other words, I need to check if base.Property is null, but by using reflection. This doesn't work, it simply gets the sub-class value (which is resolved against defaults, so not null).

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

Also tried:

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

Is it possible using reflection to access the base class value?

UPDATE:

Following advice from comments, I tried the following, just for kicks.

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

Both of these still return the "derived" value, while at the same time base.Property returns null.

like image 298
Max Avatar asked Sep 15 '25 04:09

Max


1 Answers

It is possible, although as far as I know there's no way to do it without emitting your own IL, basically using the call instruction rather than callvirt.

Note that if you need to go to these lengths to make your design work then that's a sign that you're probably doing something wrong somewhere!

Anyway, here's a contrived example. (Error-checking etc omitted for brevity.)

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);
    }
}
like image 96
LukeH Avatar answered Sep 16 '25 18:09

LukeH