C# 11 静态方法继承

huangapple go评论70阅读模式
英文:

C# 11 static method inhertance

问题

如您所见,test6 抛出了错误,但 test3 成功。有没有办法通过 Type(使用反射)检索与 test3 输出相同的值?

是的,您可以使用反射来获取与 test3 相同的值。要做到这一点,您可以在基类上使用 BindingFlags 参数,将 BindingFlags.Static 添加到 InvokeMember 方法中,以指示查找静态成员。这样,您可以通过反射调用静态属性,并获得与 test3 相同的结果。以下是如何修改您的代码:

var test6 = typeof(Subclass2).InvokeMember("MyProp", BindingFlags.GetProperty | BindingFlags.Static, null, null, null);

通过将 BindingFlags.Static 添加到 InvokeMember 中,您应该能够成功调用静态属性并获得预期的输出。

英文:

I am checking out the new static inhertance that comes with c# 11. I was trying to invoke a static member via reflection i would assume the inherited property would be executed but that doesn't seem the case and i get a MethodNotFoundException.

My code

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

As you can see test6 throws an error but test3 succeeds. Is there anyway i can retrieve the value that test3 outputs via the Type (with reflection)?

答案1

得分: 5

在C# 11中,静态成员不会被派生类继承。每个派生类都可以定义与基类相同名称的自己的静态成员,从而有效隐藏了基类的静态成员。这种行为被称为"shadowing"(遮蔽)。

在你的示例中,Subclass2没有定义自己的MyProp静态成员,所以它继承了MyBaseClassMyProp成员。这就是为什么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来获取其值。这将正确地检索继承的静态成员的值。

请记住,反射可能会对性能产生影响,通常建议尽可能直接访问静态成员。

英文:

In C# 11, static members are not inherited by derived classes. Each derived class can define its own static member with the same name as the base class, effectively hiding the base class's static member. This behavior is known as "shadowing."

In your example, Subclass2 does not define its own MyProp static member, so it inherits the MyProp member from MyBaseClass. That's why test3 correctly outputs "default."

However, when using reflection to access static members, the member lookup is not affected by shadowing. When you invoke typeof(Subclass2).InvokeMember("MyProp", BindingFlags.GetProperty, null, null, null), it searches for a static member named MyProp directly on Subclass2. Since Subclass2 does not define its own MyProp, the member is not found, and a MethodNotFoundException is thrown.

To retrieve the inherited static member via reflection, you can modify your code as follows:

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

In this code, we explicitly retrieve the MyProp property from the MyBaseClass using reflection and then get its value by passing null as the instance parameter to GetValue. This will correctly retrieve the value of the inherited static member.

Keep in mind that reflection can have performance implications, and it's generally recommended to use direct access to static members whenever possible.

huangapple
  • 本文由 发表于 2023年6月11日 20:26:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/76450473.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定