我想知道这样的事情是否可能:我重写了基类的一个属性,该属性是自动实现的。我已经在重写中提供了逻辑来解决默认设置中的"缺失"属性。
现在,我想使用反射来检查是否使用默认值或一些"实际"值。换句话说,我需要检查base.Property
是否为空,但是通过反射。这不起作用,它只是获取子类的值(根据默认值进行解析,所以不是null)。
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
返回null。
这是可能的,尽管据我所知,没有办法做到这一点而不发出自己的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);
}
}
我想这是不可能的。对象的实际类型是派生类型,根据虚拟方法的定义,无论通过哪个类型实例(实际类型或基类型)调用方法,都将获得重写的实现。
至少对我来说,以其他方式进行这项工作将是意想不到的行为。
EDIT:我尝试了以下操作,看看是否实际上有可能获得基本实现:
Type baseType = this.GetType().BaseType;
var methodInfo = baseType.GetMethod("Foo");
string foo = methodInfo.Invoke(this, null); //Derived type implementation
这意味着即使通过base
类型MethodInfo
反射调用该方法也能够解析覆盖并将返回派生实现。所以我认为你所尝试的是不可能通过反思或者至少我看不出有什么方法可以做到的