在 C# 中覆盖派生类中的常量
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/770437/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Overriding constants in derived classes in C#
提问by
In C# can a constant be overridden in a derived class? I have a group of classes that are all the same bar some constant values, so I'd like to create a base class that defines all the methods and then just set the relevant constants in the derived classes. Is this possible?
在 C# 中可以在派生类中覆盖常量吗?我有一组相同的类,其中包含一些常量值,因此我想创建一个定义所有方法的基类,然后在派生类中设置相关常量。这可能吗?
I'd rather not just pass in these values to each object's constructor as I would like the added type-safety of multiple classes (since it never makes sense for two objects with different constants to interact).
我宁愿不只是将这些值传递给每个对象的构造函数,因为我希望增加多个类的类型安全性(因为具有不同常量的两个对象进行交互永远没有意义)。
回答by Andrew Hare
Unfortunately constants cannot be overridden as they are not virtual members. Constant identifiers in your code are replaced with their literal values by the compiler at compile time.
不幸的是,常量不能被覆盖,因为它们不是虚拟成员。编译器在编译时将代码中的常量标识符替换为其文字值。
I would suggest you try to use an abstract or virtual property for what you would like to do. Those are virtual and as such can (must, in the case of an abstract property) be overridden in the derived type.
我建议您尝试将抽象或虚拟财产用于您想做的事情。这些是虚拟的,因此可以(在抽象属性的情况下必须)在派生类型中被覆盖。
回答by Tracker1
It's not a constant if you want to override it ;). Try a virtual read-only property (or protected setter).
如果你想覆盖它,它不是一个常数;)。尝试虚拟只读属性(或受保护的 setter)。
Read-only property:
只读属性:
public class MyClass {
public virtual string MyConst { get { return "SOMETHING"; } }
}
...
public class MyDerived : MyClass {
public override string MyConst { get { return "SOMETHINGELSE"; } }
}
Protected setter:
受保护的二传手:
public class MyClass {
public string MyConst { get; protected set; }
public MyClass() {
MyConst = "SOMETHING";
}
}
public class MyDerived : MyClass {
public MyDerived() {
MyConst = "SOMETHING ELSE";
}
}
回答by ivan_pozdeev
Constants marked with const
cannot be overridden as they are substituted by the compiler at compile time.
标记为 的常量const
不能被覆盖,因为它们在编译时被编译器替换。
But regular static fields assigned to constant values can. I've had such a case just now:
但是分配给常量值的常规静态字段可以。我刚才有过这样一个案例:
class Columns
{
public static int MaxFactCell = 7;
}
class Columns2 : Columns
{
static Columns2()
{
MaxFactCell = 13;
}
}
If I just redefined the MaxFactCell
field in the derived class instead, polymorphism wouldn't work: code using Columns2
as Columns
would not see the overriding value.
如果我只是MaxFactCell
在派生类中重新定义字段,则多态性将不起作用:使用Columns2
as 的代码Columns
将看不到覆盖值。
If you need to restrict write (but not read) access to the field, using readonly
would prohibit redefining it in Columns2
. Make it a property instead, that's slightly more code:
如果您需要限制对该字段的写(但不是读)访问, usingreadonly
将禁止在Columns2
. 将其改为属性,代码稍微多一些:
class Columns
{
static Columns()
{
MaxFactCell = 7;
}
public static int MaxFactCell { get; protected set; }
}
class Columns2 : Columns
{
static Columns2()
{
MaxFactCell = 13;
}
}
回答by Ji?í Skála
Edit: This can have unexpected behaviour, see Shai Petel's remark below.
编辑:这可能会有意想不到的行为,请参阅下面的 Shai Petel 的评论。
You can hide the inherited constant in a derived class by declaring the new constant new
. I'm not sure this is a good practice, though.
您可以通过声明新常量来隐藏派生类中继承的常量new
。不过,我不确定这是一个好的做法。
class A
{
protected const int MyConst = 1;
}
class B : A
{
new private const int MyConst = 2;
}
回答by Marc Ziss
to Work off dten + Tracker1's answer but updated for c# 6
解决 dten + Tracker1 的答案,但针对 c# 6 进行了更新
public class MyClass {
public virtual string MyConst =>"SOMETHING";
}
...
public class MyDerived : MyClass {
public override string MyConst =>"SOMETHING ELSE";
}
回答by Marc Ziss
You can force derived classes to have a value for a constant (well, a read-only property)
您可以强制派生类具有常量值(好吧,只读属性)
- Make an interface containing a read-only property.
- Put that interface on the base class.
- 制作一个包含只读属性的界面。
- 将该接口放在基类上。
Example:
例子:
public interface IHasConstant
{
string MyConst { get; }
}