覆盖基类静态变量

时间:2014-06-02 03:50:25

标签: c# inheritance

我试图覆盖基类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) {

    }
}

2 个答案:

答案 0 :(得分:1)

不,你不能覆盖它;常量不是虚拟成员(编译器基本上在编译期间用它们的值替换常量。)

如果您的目的是隐藏基类字段,那么执行编译器所说的内容:添加new关键字:

new public const string CLASS_NAME = "___ARC___";

答案 1 :(得分:0)

不确定你的意思 -

  

从逻辑上讲,将此解释为将变量设为私有(不要覆盖下面的答案中的真正意义)并且我需要将此变量公之于众

这似乎是矛盾的,因为 -

  1. 如果你真的需要它作为公共(我认为你指的是父类变量),那么重写它有什么意义呢?或者创建一个具有相同名称的相同变量?

  2. 如果要使用相同名称覆盖变量,则可以使用new或@Dmtry给出的解决方案。但使用new有一个好处。您可以根据需要更改变量签名。例如,以下是一个完美的编译代码 -

    public class Element {
        public const string CLASS_NAME = "___ELEMENT___";
    
    }
    
    public class Arc : Element {
        private new readonly string CLASS_NAME = "___ARC___";
    }
    
  3. 当它们是实例变量时,即使变量隐藏了父变量,您仍然可以使用类型转换或基本引用来引用父变量,如下所示 -

    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();
        }
    }
    
  4. 但是你再次使用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();
        }
    }