英文:
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
静态成员,所以它继承了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
来获取其值。这将正确地检索继承的静态成员的值。
请记住,反射可能会对性能产生影响,通常建议尽可能直接访问静态成员。
英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论