我试图覆盖基类const / static变量。但是我得到了编译器错误:
'Arc.CLASS_NAME'隐藏了继承的成员`Element.CLASS_NAME'。使用 如果隐藏意图是新关键字
有没有办法覆盖这种变量?也许我需要将数据类型更改为public virtual static readonly
?
public class Element {
public const string CLASS_NAME = "___ELEMENT___";
...
}
public class Arc : Element {
public const string CLASS_NAME = "___ARC___";
// Problem is: CLASS_NAME needs to be const to be used as a default argument
public Arc(uint nUTMZone=DEF_UTM_ZONE, string nName=CLASS_NAME) : base(nUTMZone, nName) {
}
}
答案 0 :(得分:1)
不,你不能覆盖它;常量不是虚拟成员(编译器基本上在编译期间用它们的值替换常量。)
如果您的目的是隐藏基类字段,那么执行编译器所说的内容:添加new
关键字:
new public const string CLASS_NAME = "___ARC___";
答案 1 :(得分:0)
不确定你的意思 -
从逻辑上讲,将此解释为将变量设为私有(不要覆盖下面的答案中的真正意义)并且我需要将此变量公之于众
这似乎是矛盾的,因为 -
如果你真的需要它作为公共(我认为你指的是父类变量),那么重写它有什么意义呢?或者创建一个具有相同名称的相同变量?
如果要使用相同名称覆盖变量,则可以使用new
或@Dmtry给出的解决方案。但使用new
有一个好处。您可以根据需要更改变量签名。例如,以下是一个完美的编译代码 -
public class Element {
public const string CLASS_NAME = "___ELEMENT___";
}
public class Arc : Element {
private new readonly string CLASS_NAME = "___ARC___";
}
当它们是实例变量时,即使变量隐藏了父变量,您仍然可以使用类型转换或基本引用来引用父变量,如下所示 -
public class Element
{
public string CLASS_NAME = "___ELEMENT___";
}
public class Arc : Element
{
public new string CLASS_NAME = "___ARC___";
}
public class Program
{
public static void Main(string[] args)
{
Arc a = new Arc();
Console.WriteLine(a.CLASS_NAME);
Console.WriteLine((a as Element).CLASS_NAME);
Console.ReadLine();
}
}
但是你再次使用static
变量,所以你可以访问它们的唯一方法是使用ClassName
,因此覆盖的重点不应该是问题,因为你总是可以通过class,而不是实例,所以你总是知道你正在使用哪个变量.-
public class Element
{
public const string CLASS_NAME = "___ELEMENT___";
}
public class Arc : Element
{
public new const string CLASS_NAME = "___ARC___";
}
public class Program
{
public static void Main(string[] args)
{
Arc a = new Arc();
Console.WriteLine(Arc.CLASS_NAME);
Console.WriteLine(Element.CLASS_NAME);
Console.ReadLine();
}
}