C# 覆盖非虚拟财产
我知道在C#中,我们不能覆盖非虚拟字段和方法,但我有以下情况:C# 覆盖非虚拟财产,c#,inheritance,C#,Inheritance,我知道在C#中,我们不能覆盖非虚拟字段和方法,但我有以下情况: Class Base { public static int a {get;set;} public static void b() { // it uses a } public static void c() { // it uses a } public static string d {get {return a.ToString();}} } C
Class Base
{
public static int a {get;set;}
public static void b()
{
// it uses a
}
public static void c()
{
// it uses a
}
public static string d {get {return a.ToString();}}
}
Class MyClass :Base
{
//...
}
现在,在我的类MyClass
中,我想覆盖属性a
,所有基类
方法和属性都开始使用我实现的覆盖属性,考虑到我无权更改基类
即使我必须使用该属性的getter方法,还有什么方法可以做到这一点吗?最好的方法可能是使用不同的名称引入一个新属性,或者让您的类包装基类,而不是扩展它。与扩展方法一起,这些是基于您无权访问的类的功能构建的最常见方法 您还可以使用
new
关键字重新引入属性,但我不建议这样做。它隐藏了基类方法,这很危险,因为代码的用户可能最终调用错误的东西。在这种情况下,new
是否得到保证在很大程度上取决于您的确切用例
最后请注意,正如Daniel在原始帖子的评论中所说,基类中的方法似乎是静态的。因此,即使您具有基类访问权限,也无法使它们
虚拟化
。实际上,除了对象工厂或扩展方法容器等特殊情况外,加载静态方法通常是糟糕的设计。最好的方法可能是使用不同的名称引入新属性,或者让类包装基类而不是扩展它。与扩展方法一起,这些是基于您无权访问的类的功能构建的最常见方法
您还可以使用new
关键字重新引入属性,但我不建议这样做。它隐藏了基类方法,这很危险,因为代码的用户可能最终调用错误的东西。在这种情况下,new
是否得到保证在很大程度上取决于您的确切用例
最后请注意,正如Daniel在原始帖子的评论中所说,基类中的方法似乎是静态的。因此,即使您具有基类访问权限,也无法使它们
虚拟化
。实际上,除了对象工厂或扩展方法容器等特殊情况外,加载静态方法通常是不好的设计。这是一个静态属性,因此在Base.a
表单中使用。无论您做什么,调用代码仍将解析为Base
类,然后解析为它的静态属性a
例如
这是一个静态属性,因此它以
Base.a
的形式使用。无论您做什么,调用代码仍将解析为Base
类,然后解析为它的静态属性a
例如
为什么你有所有的静态方法@DanielA.White从.net framework生成的文件中删除它.net framework不生成类(除非您告诉它)请elavorate.@DanielA.White我刚才说的是资源文件和“PublicResXFileCodeGenerator”为什么您有所有的静态方法@DanielA.White从.net framework生成的文件中删除它.net framework不会生成类(除非您告诉它)请elavorate.@DanielA.White我刚才说的是资源文件和“PublicResXFileCodeGenerator”,根据问题的要求,它不会引入覆盖语义。也不需要使用
new
在继承类中拥有相同名称的属性;由于属性是静态的,所以实际上没有任何阴影。正确的,获得正确覆盖的唯一方法是使基本方法虚拟。隐藏基类属性和组合是我知道的唯一选择。但是,它们有不同的用途,选择哪一个取决于OP为什么要做他们想做的事情。属性是静态的,所以如果他希望它是虚拟的,它甚至不能是虚拟的。是的,这是代码的另一个问题,正如Daniel在注释中已经指出的。这并没有引入覆盖语义,正如问题所要求的那样。也不需要使用new
在继承类中拥有相同名称的属性;由于属性是静态的,所以实际上没有任何阴影。正确的,获得正确覆盖的唯一方法是使基本方法虚拟。隐藏基类属性和组合是我知道的唯一选择。但是,它们有不同的用途,选择哪一个取决于OP为什么要做他们想要做的事情。属性是静态的,所以如果他希望它是虚拟的,它甚至不能是虚拟的。是的,这是代码的另一个问题,正如Daniel在注释中已经指出的。是的,你是对的,我只是有点困惑。谢谢是的,你是对的,我只是有点困惑。非常感谢。
//old calling code
Base.a = 7; // does not create an instance
Console.WriteLine(Base.a);
class MyClass :Base
{
public static string a {get; set;}
}
//new calling code
MyClass.a = "some string"; // uses whatever a you defined in MyClass
Console.WriteLine(MyClass.a);