6

代码 :

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

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

}

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

The modifier 'virtual' is not valid for this item

4

5 回答 5

13

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

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

使用此解决方案时,您应该考虑一些问题。以下面的控制台程序为例:

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
    {

    }
}

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

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

于 2013-03-01T13:09:54.453 回答
8

字段(包括常量)不能是虚拟的。这与它是一个常量无关......这只是字段的工作方式......尽管常量是隐式静态的事实使得它不可行,因为它是。

如果你想要多态行为,它必须通过一个实例成员,它是一个属性、方法或事件。

顺便说一句,我强烈怀疑您的“const出于性能原因我想要它”的理由是虚假的微优化。甚至不清楚你是如何使用它的,但我非常怀疑你是否尝试过它作为非常数并证明它太慢了。

于 2013-03-01T13:05:48.730 回答
5

常量不能被覆盖,它们是常量。

如果您希望通过扩展来更改此值,那么您将需要使用较少的常量,具有根据上下文更改的性质,例如abstract要实现或virtual覆盖的元素。

于 2013-03-01T13:05:32.363 回答
5

实际上,我相信您误解了面向对象编程中多态性的意义。

常量、字段和变量只是一种存储(嗯,引用,但我是从概念的角度说的)。

多态性是关于改变某物的行为。覆盖一个常量不能改变一个行为,而是改变它的值

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

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

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;

抓住!如果一个常量是静态的,C.Some即使2没有C覆盖任何常量!

您的问题中的一些引用:

由于性能,我希望它与 const int 一样明确。[...]

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

正如 Jon Skeet 所说,这将是您最不关心的问题。

于 2013-03-01T13:28:29.297 回答
3

你可以这样做我猜:

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

public class B : A
{
    public override Int32 beingSupportedRate 
    {
        get { return 1; }
    }
}
于 2013-03-01T13:15:16.800 回答