2011-05-01 69 views
34

abstract基类中,如果我们有一些static字段,那么它们会发生什么?基类和派生类中的静态字段

它们的范围是从这个基类继承的类还是它继承的类型(每个子类都有自己的基类的static字段副本)?

+0

BTW,事实上,基类是'abstract'是一个红色的鲱鱼;无论基类是否为'abstract',行为@Marc Gravell指出的行为都是一样的。 – casperOne 2011-05-01 21:31:43

+0

@casperOne:我正在寻找'TypeLocal '这样的东西,因为我们有'ThreadLocal ',所以这个类型的任何对象在它的相应'子类'中都是'static'。 – Xaqron 2011-05-01 21:48:59

回答

54

static成员完全专用于声明 class;子类不会获得单独的副本。这里唯一的例外是泛型;如果开放泛型类型声明静态字段,则该字段特定于组成闭合泛型类型的类型参数的确切组合组合;即Foo<int>将具有单独的静态字段到Foo<string>,假定字段在Foo<T>上定义。

+0

@Marc Gravell:对不起,你和@Jon Skeet教我迂腐;你的意思是说“类型参数”而不是“静态参数”。 =)希望一切都很好,穿过池塘。 – casperOne 2011-05-01 21:26:29

+2

如何从'base class'声明所有实例(每个类型)的唯一变量? – Xaqron 2011-05-01 21:27:11

+0

@Xaqron:你不能,你必须在每个派生类上重新声明你想要的静态成员。 – casperOne 2011-05-01 21:29:06

8

正如在其他答案中指出的那样,基类静态字段将在所有子类之间共享。如果你需要为每个最终子类的单独副本,您可以使用一个静态字典,一个子类的名字作为键:

class Base 
{ 
    private static Dictionary<string, int> myStaticFieldDict = new Dictionary<string, int>(); 

    public int MyStaticField 
    { 
     get 
     { 
      return myStaticFieldDict.ContainsKey(this.GetType().Name) 
        ? myStaticFieldDict[this.GetType().Name] 
        : default(int); 
     } 

     set 
     { 
      myStaticFieldDict[this.GetType().Name] = value; 
     } 
    } 

    void MyMethod() 
    { 
     MyStaticField = 42; 
    } 
}