C#中受保护的静态字符串可访问性问题

时间:2016-01-27 21:22:33

标签: c# generics

我有一个抽象的基类,它是模板化的。

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另一方面是静态保护功能,则此问题不存在,这使整个事情更加不清楚。

2 个答案:

答案 0 :(得分:7)

  

为什么Derived1可以访问Derived2的受保护静态成员?

MAGIC位于公共基类中,而不是Derived2中。 Base<T>的任何子类都会看到同名的变量,但如果每个派生类的T不同,它实际上将是不同的变量。

  

我认为静态构造函数在访问任何静态成员之前运行,为什么当我访问Derived2.MAGIC时,我没有看到它的静态构造函数被调用?

没有声明Derived2.MAGIC,声明Base<T>.MAGICDerived1正在访问在其自己的基类中声明的受保护字段。

您首先假设MAGIC在Derived2中声明。如果你改变你的代码实际上是这样的话,那么你的期望就会存在。

答案 1 :(得分:1)

虽然Eric J已经彻底解释过了,但我想补充说明,MAGIC似乎有两个值的原因之一是因为泛型类中有 - static个成员表现得有点神奇,因为每个泛型重载都会有不同的字段,即Base<Other1>.MAGICBase<Other2>.MAGIC。如果您使用非泛型Base尝试此相同示例,则继承行为可能更明显,在这种情况下,您将看到MAGIC仅存在一次,并且来自任一派生类的更改将影响同一字段。