我正在检查C# 11附带的新静态继承。我试图通过反射调用一个静态成员,我会假设继承的属性将被执行,但似乎不是这样,我得到一个MethodNotFoundException。
我的准则
public abstract class MyBaseClass {
public static string MyProp { get => "default";}
}
public class Subclass1 : MyBaseClass {
public static new string MyProp { get => "myprop";}
}
public class Subclass2 : MyBaseClass {
}
public static class Program {
public static void Main(string[] args)
{
// outputs "default"
var test1 = MyBaseClass.MyProp;
// outputs "myprop"
var test2 = Subclass1.MyProp;
// outputs "default"
var test3 = Subclass2.MyProp;
// outputs "default"
var test4 = typeof(MyBaseClass).InvokeMember("MyProp", BindingFlags.GetProperty,null,null,null);
// outputs "myprop"
var test5 = typeof(Subclass1).InvokeMember("MyProp", BindingFlags.GetProperty,null,null,null);
//throws exception
var test6 = typeof(Subclass2).InvokeMember("MyProp", BindingFlags.GetProperty,null,null,null);
}
}
正如你所看到的,test6
抛出一个错误,但test3
成功。我是否可以通过Type
(带反射)检索test3
输出的值?
1条答案
按热度按时间umuewwlo1#
在C# 11中,静态成员不会被派生类继承。每个派生类都可以用与基类相同的名称定义自己的静态成员,从而有效地隐藏基类的静态成员。这种行为被称为“遮蔽”。
在您的示例中,
Subclass2
没有定义自己的MyProp
静态成员,因此它继承了MyBaseClass
中的MyProp
成员。这就是为什么test3
正确地输出“default”。但是,当使用反射访问静态成员时,成员查找不受阴影影响。调用
typeof(Subclass2).InvokeMember("MyProp", BindingFlags.GetProperty, null, null, null)
时,它会直接在Subclass2
上搜索名为MyProp
的静态成员。由于Subclass2
没有定义自己的MyProp
,因此找不到该成员,并抛出了MethodNotFoundException
。要通过反射检索继承的静态成员,可以修改代码如下:
在这段代码中,我们使用反射从
MyBaseClass
中显式检索MyProp
属性,然后通过将null
作为示例参数传递给GetValue
来获取其值。这将正确检索继承的静态成员的值。请记住,反射可能会影响性能,通常建议尽可能使用对静态成员的直接访问。