.net C#11静态方法继承

a6b3iqyw  于 2023-06-25  发布在  .NET
关注(0)|答案(1)|浏览(148)

我正在检查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输出的值?

umuewwlo

umuewwlo1#

在C# 11中,静态成员不会被派生类继承。每个派生类都可以用与基类相同的名称定义自己的静态成员,从而有效地隐藏基类的静态成员。这种行为被称为“遮蔽”。
在您的示例中,Subclass2没有定义自己的MyProp静态成员,因此它继承了MyBaseClass中的MyProp成员。这就是为什么test3正确地输出“default”。
但是,当使用反射访问静态成员时,成员查找不受阴影影响。调用typeof(Subclass2).InvokeMember("MyProp", BindingFlags.GetProperty, null, null, null)时,它会直接在Subclass2上搜索名为MyProp的静态成员。由于Subclass2没有定义自己的MyProp,因此找不到该成员,并抛出了MethodNotFoundException
要通过反射检索继承的静态成员,可以修改代码如下:

var baseProp = typeof(MyBaseClass).GetProperty("MyProp", BindingFlags.Public | BindingFlags.Static);
var test6 = baseProp.GetValue(null);

在这段代码中,我们使用反射从MyBaseClass中显式检索MyProp属性,然后通过将null作为示例参数传递给GetValue来获取其值。这将正确检索继承的静态成员的值。
请记住,反射可能会影响性能,通常建议尽可能使用对静态成员的直接访问。

相关问题