2012-05-24 114 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我個人從未建議實際使用這種解決方案,它是一個巨大的代碼氣味。如果我知道你想達到什麼目的,我可以提供一個更合適的解決方案,但就目前而言,你的問題都不是很清楚。 –