同事報案,遇到一宗罕見的 .NET Namespace 命名衝突問題,我用以下專案結構模擬案發現場:

專案 Darkthread.Mobile 參照了 Utility 與 Darkthread.Utility 兩個 Class Library 專案。

Utility 專案有個 Uitlity.ResultL1 類別:

namespace Utility 
{
    public class ResultL1 { }    
}

Darkthread.Utility 專案則有個 Darkthread.Utility.ResultL2 類別:

namespace Darkthread.Utility 
{
    public class ResultL2 { }
}

兩個類別名稱不同,所屬命名空間也不同,照理不致發生衝突。但狀況是 Darkthread.Mobile 專案中可以引用 Darkthread.Utility.ResultL2,但無法引用 Utility.ResultL1。如下圖,即使輸入 "Utility.ResultL1",Visual Studio 也會自動冠上 Darkthread,解讀成 Darkthread.Utility.ResultL1 而找不到型別:

腦海閃過一個關鍵字 "global::",印象中在某些程式碼產生器輸出結果滿坑滿谷都是,直覺可以用在這裡。在 Utility.ResultL1 前方加上 global::,問題還真的解決了!

事後爬文,找到 "" 的官方文件說明 可以用來串接命名空間別名,例如 System.Drawing 跟 System.Windows 命名空間都有名為 Point 的類別,需要同場演出時可以用這招;

using forwinforms = System.Drawing;
using forwpf = System.Windows;

public class Converters
{
    public static forwpf::Point Convert(forwinforms::Point point) => new forwpf::Point(point.X, point.Y);
}

而 global:: 則相當於強調命名空間的絕對性,與相對命名空間做出區別,聲明前方未省略父系命名空間名稱,完整命名空間就是這整串文字。

過去看過無數遍,今天第一次體驗到它的用處,學到一則冷知識。

A real case of using global:: namespace aliase to resolve class name conflict.


Comments

# by CoCo

中間有一行=>即使輸入 "Darkthread.ResultL1",Visual Studio 也會自動冠上 Darkthread,是不是應該為 Utility.ResultL1才對?

# by Jeffrey

to CoCo, 對,我寫錯了,謝謝指正。

Post a comment