2012-05-24 62 views
3

简单问题:静态变量是他们的类实例变量?

静态变量是class instance variable还是class variable基?

了解class instance variable是为每个定义的类和子类定义的变量。 和class variable是对所有子类全局的变量,包括它自己在内的所有子类。

编辑:知道我窒息了很多C#的人我使用术语类实例,就好像一个类,其中一些MetaClass的实例。这大大简化了我的问题。虽然说如果你认为VM肯定有代表evrey类的工件(包含方法dictionay,实例大小,超类,...)并不完全错误。 谢谢

回答

1

它们是类变量。 在C#中没有什么像Smalltalk类的实例变量。即没有办法定义一个在类的所有实例中通用的变量,但是它的子类具有不同的值。

为了获得一个“类似”的行为,但其缺点在于类实例VAR仅在已经创建类的实例,我已经做了这样的事情后,可访问:

public class BaseClass 
{ 
    private static Dictionary<Type, object> ClassInstVarsDict = new Dictionary<Type, object>(); 

    public object ClassInstVar 
    { 
     get 
     { 
      object result; 
      if (ClassInstVarsDict.TryGetValue(this.GetType(), out result)) 
       return result; 
      else 
       return null; 
     } 
     set 
     { 
      ClassInstVarsDict[this.GetType()] = value; 
     } 
    } 
} 

public class DerivedClass1 : BaseClass 
{ 
} 

public class DerivedClass2 : BaseClass 
{ 
} 
+0

感谢您的建议。还有一个缺点,就是ClassInstVar只能是一个实例属性。它不能是类方(“aka kindof static”) – mathk

+0

@mathk现在我可能会理解你想要什么,我已经用另一种方式修改了我的答案。 –

9

静态变量“属于”类型 - 它们不是实例变量。

也就是说,它们之间共享的所有类型的实例,包括generic封闭构造类型。

例外情况是用ThreadStatic修饰的静态变量,使变量在一个线程中唯一。

+2

值得注意的是,泛型将意味着静态属于类型,且泛型参数也被考虑在内。 –

+1

静态变量也在线程之间共享。 –

+0

@AdamHouldsworth - 确实如此。在泛型类型上定义的静态将在[封闭构造泛型类型](http://msdn.microsoft.com/en-us/library/sz6zd40f.aspx)的实例之间共享。 – Oded

4

静态变量适用于给定的AppDomain中定义的类型。它们也跨线程共享,除非您使用ThreadStaticAttribute,此时它们变为线程。

类成员明显限定为该类的实例,但不是派生类的“全局”类。根据访问修饰符,成员对派生实例也可以是可见的。

类与一般的参数有每个封闭泛型类型的静态变量:

class MyClass<T> 
{ 
    public static string Name; 
} 

所以MyClass<int>将拥有自己的NameMyClass<string>副本都有一个不同的副本。


看看你选择的答案,好像你想为每个派生类的静态变量?

你可以欺骗和使用上面的泛型规则:

class Program 
{ 
    static void Main(string[] args) 
    { 
     Derived1.WhatClassAmI = "Derived1"; 
     Derived2.WhatClassAmI = "Derived2"; 

     Console.WriteLine(Derived1.WhatClassAmI); // "Derived1" 
     Console.WriteLine(Derived2.WhatClassAmI); // "Derived2" 

        Console.WriteLine(BaseClass<Derived1>.WhatClassAmI); // "Derived1" 
        Console.WriteLine(BaseClass<Derived2>.WhatClassAmI); // "Derived2" 
     Console.Read(); 
    } 

    class BaseClass<T> where T : BaseClass<T> 
    { 
     public static string WhatClassAmI = "BaseClass"; 
    } 

    class Derived1 : BaseClass<Derived1> 
    { 
    } 

    class Derived2 : BaseClass<Derived2> 
    { 
    } 
} 

他们用“同一”一成不变的,而是各有因型封闭自己的价值观。

+0

不用多说,完全是逻辑,因为具有不同类型参数的泛型类的每个实例都会产生具有不同类型的对象。 – mathk

+0

有趣的解决方案,虽然我不太喜欢它,因为它不是很明显发生了什么。我不想对那些将我的代码保持在我身后的人解惑。所以我决定添加一个抽象属性,并在每个子类中“重新定义”一个静态变量。 – mathk

+0

@mathk我个人从未建议实际使用这种解决方案,它是一个巨大的代码气味。如果我知道你想达到什么目的,我可以提供一个更合适的解决方案,但就目前而言,你的问题都不是很清楚。 –