C# 如何重写常量派生类?
代码: 由于性能原因,我希望它与常量int一样明确。 将virtual放在C# 如何重写常量派生类?,c#,C#,代码: 由于性能原因,我希望它与常量int一样明确。 将virtual放在类A变量beingSupportedRate前面会导致以下编译器错误: 修饰符“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;