2014-11-04 41 views
3

從C++背景來看,我需要一些時間才能習慣C#。在C#中,使用點運算符(。)的次數要比:: - 運算符(C#中的命名空間限定符運算符)多得多,以訪問命名空間和類作用域。C# - 爲什麼:: - 運算符與全局關鍵字而不是點運算符關聯?

在C++中,使用點運算符(。)來訪問類實例的成員。另一方面,範圍解析運算符(:)用於訪問沒有該類的實例的類的成員。對我而言,這是有道理的,既合乎邏輯又一致。

雖然我可以接受在C#中使用的不同方法,但似乎至少有一個實例,我在其中看到不一致。至少,這是我看來的樣子。它與全球的關鍵字做:爲什麼需要命名空間別名限定符全球的關鍵字,而不是點運算符來使用我

global::System.Console.WriteLine("Hello World"); 

有人能解釋一下嗎?

+0

*本身*? – 2014-11-04 08:52:55

+0

將C#和C++之間的對待視爲事故,而不是設計目標。它的可能性與它在C++中引起的麻煩數量成反比。這是一個*很多*,在C++中的名稱解析是非常複雜的。 Microsoft C++編譯器今天仍然存在重大錯誤。 – 2014-11-04 12:00:20

回答

1

這並不常見,但在某些情況下它很方便。

想象一下,你有這樣的一類System當前命名空間:

namespace Test { 
    static class System { 
     public static Do() { } 
    } 

    class Foo { 
     void foo() { 
      System.Do(); // What's this? 
     } 
    } 
} 

你想使之更加複雜化?在System中添加一個內部類並調用它,例如Action。當然,這些都是邊緣情況,可能你永遠不會需要使用global::,但語言本身必須處理這種情況。有關更多示例,請參閱MSDN

全局命名空間的別名也是另一種情況很有用:當您引用兩個DLL和他們有相同的命名空間和類(例如,因爲他們根本是兩個版本相同東西)。在那種情況下,你如何引用它們?相同的problem described here for C++。您可以更改名稱空間以包含版本號,但每次更改時都很痛苦(並且VS自動重構AFAIK不能與名稱空間一起使用),或者您可以使用兩個別名引用它們。他們將訪問,例如,像這樣:

Version1::CompanyName.MyNamespace.MyClass 
Version2::CompanyName.MyNamespace.MyClass 

另外請注意,這是一個很好的做法(包括global::命名空間),當你生成代碼(例如所有設計師生成的代碼),因爲你唐不知道在哪種情況下代碼將被編譯(然後可能發生衝突)。


推理::.好...這不是這麼一個問題(除非你是幸運的埃裏克是有一些在這裏樂趣SO),但我可能會想這是因爲他們是不同的東西。如果使用相同的運算符.,那麼解析器如何理解global.System要使用全局名稱空間別名,而不是名爲global的類或名稱空間?他們不得不做出global保留關鍵字,因爲`global`是*命名空間別名*的(實際上匿名)全局命名空間,而不是一個命名空間也不會解決衝突的層次其他問題...

+2

當然,任何創建他們自己的類名爲「系統」的人都需要對他們的頭進行檢查。如果你發現你需要使用'global ::',那麼你可能做錯了什麼。 – 2014-11-04 15:06:51

+0

@DaveDoknjas絕對!這有一點點_worse_因爲同樣的考慮適用於屬性,內部類和字段,但是是...非常罕見。 – 2014-11-04 15:14:30