我有一个抽象的基类,它是模板化的。
public abstract class Base<T> where T : new()
{
protected static string MAGIC;
}
然后我有两个类派生自Base
,但T
的值不同。
public class Derived1:Base<Other1> {}
public class Derived2:Base<Other2> {}
似乎正在发生两件奇怪的事情。首先,Derived2.MAGIC
可以从Derived1
的成员函数中获得;我不指望那样。此外,Derived2
有一个静态构造函数,用于设置MAGIC
;奇怪的是,Derived2
访问Derived1
时不会调用Derived2.MAGIC
的静态构造函数(甚至不允许这样做)。
两个问题:
为什么Derived1
可以访问Derived2
的受保护静态成员?
我认为静态构造函数在访问任何静态成员之前运行,为什么当我访问Derived2.MAGIC
时,我没有看到它的静态构造函数被调用?
这两个似乎都是严重的错误。
只是添加一条注释,如果MAGIC另一方面是静态保护功能,则此问题不存在,这使整个事情更加不清楚。
答案 0 :(得分:7)
为什么
Derived1
可以访问Derived2
的受保护静态成员?
MAGIC
位于公共基类中,而不是Derived2
中。 Base<T>
的任何子类都会看到同名的变量,但如果每个派生类的T
不同,它实际上将是不同的变量。
我认为静态构造函数在访问任何静态成员之前运行,为什么当我访问
Derived2.MAGIC
时,我没有看到它的静态构造函数被调用?
没有声明Derived2.MAGIC
,声明Base<T>.MAGIC
。 Derived1
正在访问在其自己的基类中声明的受保护字段。
您首先假设MAGIC在Derived2
中声明。如果你改变你的代码实际上是这样的话,那么你的期望就会存在。
答案 1 :(得分:1)
虽然Eric J已经彻底解释过了,但我想补充说明,MAGIC
似乎有两个值的原因之一是因为泛型类中有 - static
个成员表现得有点神奇,因为每个泛型重载都会有不同的字段,即Base<Other1>.MAGIC
和Base<Other2>.MAGIC
。如果您使用非泛型Base
尝试此相同示例,则继承行为可能更明显,在这种情况下,您将看到MAGIC
仅存在一次,并且来自任一派生类的更改将影响同一字段。