2017-10-05 142 views
4

我最近開始學習C#,並且對某些東西感到困惑。靜態類的documentation告訴我他們只能包含靜態成員。然而,我可以在靜態類中定義非靜態嵌套類和結構。爲什麼C#靜態類包含非靜態類/結構體?

我猜測類/結構定義不包括成員,但爲什麼這是允許的?如果一個靜態類的嵌套類可以被實例化,是不是與靜態類的觀點相矛盾?我在這裏誤解了一些明顯的東西嗎?

+0

不好措辭,我的意思是說嵌套類。 –

+0

我會說你錯過了明顯的......靜態類的主要目的是防止該類的實例化。 – Phil1970

+0

我認爲嵌套類是它的封閉類的*靜態成員*,不管它是否是靜態類*。 (這與Java不同,Java中嵌套類不是*永遠是封閉類的靜態成員,而術語「靜態類」意味着*是靜態成員的嵌套類。) –

回答

7

在C#嵌套類不是子類,周圍的類更像是另一個名稱空間。您不能從內部類中訪問外部類的實例(與f.e. Java相反)。這就是爲什麼靜態類可以包含嵌套類型。

一個着名的例子,它是靜態的LINQ class Enumerable。它包含許多幫助類:

public static class Enumerable 
{ 
    // many static LINQ extension methods... 

    class WhereEnumerableIterator<TSource> : Iterator<TSource> 
    { 
     // ... 
    } 

    internal class EmptyEnumerable<TElement> 
    { 
     public static readonly TElement[] Instance = new TElement[0]; 
    } 

    public class Lookup<TKey, TElement> : IEnumerable<IGrouping<TKey, TElement>>, ILookup<TKey, TElement> 
    { 
     // ... 
    } 

    // many others 
} 

所以周圍的靜態類是內部類的邏輯容器。它屬於那裏,因爲它是從靜態類中使用的,並且通常不能從其他地方訪問(如果不公開)。

但是你說得對,這是缺乏文檔。他們應該說:

只包含靜態成員或嵌套類型

對我而言
+0

從某種意義上說,嵌套類類定義是靜態的。 – Haukinger

+0

@Haukinger:不,您可以創建多個實例:var i1 = new OuterC.InnerC(); var i2 = new OuterC.InnerC();'(如果可以訪問) –

+0

當然,定義的類型可能是靜態的或者不是,但_defnition_是靜態的。你不寫'var x = new OuterC(); var y = new x.InnerC();'... – Haukinger

4

該文檔有點缺乏,但嵌套的類/結構體允許在靜態類中,也可以是靜態的,或者可以實例化。請看下面的代碼:

namespace StaticClasses 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      new Foo(); // Cannot create an instance of the static class 'Foo' 
      new Foo.Bar(); // Cannot create an instance of the static class 'Foo.Bar' 
      new Foo.Baz(); 
     } 
    } 

    static class Foo 
    { 
     public static class Bar 
     { 

     } 

     public class Baz 
     { 

     } 
    } 
} 

在此背景下,靜態類類似的命名空間,但命名空間(可能)描述的語義關係比嵌套類更好。