C# 如何重写常量派生类?

C# 如何重写常量派生类?,c#,C#,代码: 由于性能原因,我希望它与常量int一样明确。 将virtual放在类A变量beingSupportedRate前面会导致以下编译器错误: 修饰符“virtual”对此项无效不能重写常量,它们是常量 如果希望此值可以通过扩展进行更改,则需要使用常数较小的值,并根据上下文进行更改,例如要实现的抽象元素或要覆盖的虚拟。字段(包括常数)不能是虚拟的。这与它是一个常数无关。。。这就是田地的工作方式。。。尽管事实上常数是隐式静态的,这使得它更不可行 如果您想要多态行为,则必须通过实例成员(属性、方法

代码:

由于性能原因,我希望它与常量int一样明确。 将virtual放在
类A
变量
beingSupportedRate
前面会导致以下编译器错误:


修饰符“virtual”对此项无效

不能重写常量,它们是常量

如果希望此值可以通过扩展进行更改,则需要使用常数较小的值,并根据上下文进行更改,例如要实现的
抽象
元素或要覆盖的
虚拟

字段(包括常数)不能是虚拟的。这与它是一个常数无关。。。这就是田地的工作方式。。。尽管事实上常数是隐式静态的,这使得它更不可行

如果您想要多态行为,则必须通过实例成员(属性、方法或事件)来实现


另一方面,我强烈怀疑您的“出于性能原因,我希望它是
const
”理由是虚假的微观优化。甚至不清楚您是如何使用它的,但我非常怀疑您是否尝试将其作为非常量,并证明它太慢。

您应该使用
new
关键字显式隐藏继承的成员:

public class A {
    public const int beingSupportedRate = 0;
}

 public partial class B : A {
    public const int beingSupportedRate = 1;

}
请记住,您不能从实例访问常量成员

public class A
{
    public const int beingSupportedRate = 0;
}

public class B : A
{
    public new const int beingSupportedRate = 1;
}
输出:

Console.WriteLine(A.beingSupportedRate);
Console.WriteLine(B.beingSupportedRate);
当使用这个解决方案时,你应该考虑一些问题。以以下控制台程序为例:

0
1
这将为所有三个类实例输出
0
,因为继承的方法使用A中的常量值。这意味着您必须重写引用该常量的所有方法


首选方法是使用具有必须实现的属性的接口,而不是为此目的使用常量。

U可以做到这一点,我想:

class Program
{
    static void Main(string[] args)
    {
        A a = new A();
        B b = new B();
        C c = new C();

        a.GetBeingSupportRate();
        b.GetBeingSupportRate();
        c.GetBeingSupportRate();

        Console.Read();
    }

    public class A
    {
        public const int beingSupportedRate = 0;
        public void GetBeingSupportRate()
        {
            Console.WriteLine(beingSupportedRate);
        }
    }

    public class B : A
    {
        public new const int beingSupportedRate = 1;

    }

    public class C : B
    {

    }
}

事实上,我相信你误解了面向对象编程中多态性的观点

常量、字段和变量只是一个存储(好吧,引用,但我是从概念的角度讲的)

多态性是指改变某些事物的行为。重写常量不能更改行为,而是更改其值

另一点是常量是静态的,因此它不属于实例,但在
AppDomain
中有一个不可变的单一值,并且它在应用程序生命周期中仍然存在

使用上面的语句,为什么要像实例成员一样重写常量?你能想象下一种情况吗

public class A 
{
    public virtual Int32 beingSupportedRate
    { 
        get { return 0; }
    }
}

public class B : A
{
    public override Int32 beingSupportedRate 
    {
        get { return 1; }
    }
}
等一下!如果常数是静态的,
C.Some
将是
2
,即使
C
没有覆盖任何常数

有人引用了你的问题:

由于性能原因,我希望它与常量int一样明确。[……]

这只有一个答案:过早的优化是任何软件开发的魔鬼


,这将是您最不关心的问题。

我认为这忽略了一点,即任何字段都不能被重写。我还没有证明这一点。回到我的C++ C++知识,我认为运行时变量会慢很多。b) 在大多数情况下,这并不重要。考虑到你甚至还没有达到你想要的行为,性能是你最不关心的问题。@JonSkeet我如何在继承层次结构中实现依赖类型的常量?假设我有一些UI控件类,它们都有一些默认维度(即按钮的默认大小与面板的默认大小不同)。有些控件相互派生,但它们的默认维度仅依赖于控件类型(即类类型)。我猜应该是一个公共静态只读属性或“这只是一个糟糕的设计”:D.Oh,我忘了。我之所以需要它作为公共常量,是因为我想在其他代码段中也像使用
按钮.DefaultWidth
面板.DefaultWidth
一样使用它。在本文中会想到
int.MaxValue
之类的东西,但是
Int32
很幸运,没有带有
MaxValue
常量/属性的基类@罗伯茨:我建议你问一个新问题,包括所有相关的细节,包括你试过的。谢谢。然而,这不是常数。这是一个运行时属性。这是一个糟糕的解决方案,因为如果某个类
a
成员访问基本常量,当某些成员调用从
a
继承的成员时,整个成员将访问该常量的非重用标识符@MatíasFidemraizer你能用不同的措辞吗?我不太明白你的意思。@JohnWillemse总结:这不是覆盖。这是一个标识符重用。只需编写自己的测试代码,并实现一个方法“DoStuff”,返回
a
类上
beingSupportedRate
常量的值,然后创建类
B
的实例。现在调用
DoStuff
。现在执行整个
Console.WriteLine(b.DoStuff())
。要打印什么?@JohnWillemse检查代码。这表明你的答案(在我看来)是多么错误。@JohnWillemse太棒了!现在你的答案是完整的:这是你的问题的答案吗?
public class A 
{
      public virtual const int Some = 1;
}

public class B : A
{
      public override const int Some = 2;
}

public class C : A
{
     // No override here!
}

int valueOfSomeConstant = C.Some;