如何覆盖常量派生类?

时间:2013-03-01 13:04:28

标签: c#

代码:

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

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

}

由于性能的原因,我希望它像const int一样显式。 将虚拟放在class A变量beingSupportedRate之前会导致编译器错误:

The modifier 'virtual' is not valid for this item

5 个答案:

答案 0 :(得分:12)

您应该使用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中的常量值。这意味着您必须覆盖引用该常量的所有方法。

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

答案 1 :(得分:6)

字段(包括常量)不能是虚拟的。这与它是一个常数无关......它只是字段的工作方式......虽然常量是隐式静态的事实使它甚至更少可行,因为它。

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

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

答案 2 :(得分:5)

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

如果您希望此值可以通过扩展名进行更改,那么您需要使用少于常量的内容,并且具有根据上下文更改的性质,例如abstract元素实施或virtual覆盖。

答案 3 :(得分:4)

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

常量,字段和变量只是存储(好吧,引用,但我从概念的角度来看)。

多态性是关于改变某事的行为。覆盖常量不能更改行为,但更改其值

另一点是常量是静态,因此它不属于实例,但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所说,这将是你问题中最少的。

答案 4 :(得分:3)

你可以这样做我猜:

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

public class B : A
{
    public override Int32 beingSupportedRate 
    {
        get { return 1; }
    }
}