[你必须知道的.NET]第二十八回:说说Name这回事儿
1 緣起
老趙在談表達式樹的緩存(2):由表達式樹生成字符串中提到,在描述Type信息時討論FullName或者AssemblyQualifiedName提供完整的Type信息,雖是小話題,但卻是值得有聊的話題。在.NET中反應一個Type名稱信息的有以下三個屬性,分別是:
- Name,獲取當前成員的名稱。
- FullName,獲取Type 的完全限定名,包括Type的命名空間,但不包括程序集。
- AssemblyQualifiedName,獲取Type的程序集限定名,其中包括從中加載Type 的程序集的名稱。事實上,AssemblyQualifiedName被定義為只讀abstract屬性,具體的實現由其派生類來實現,例如TypeBuilder,我們可以根據其具體實現類型對此有個大致的了解。
此處的定義毋庸置疑是官方的(MSDN),俗話說,事實是檢驗真理的唯一標準,那么這三個相近的概念,究竟代表了怎樣的不同,我們回到事實近看分曉。
2 暢聊Name
2.1 由簡單的開始
由簡單開始,我們不妨看看object的三個不同Name返回的事實真相:
static void Main(string[] args) {Type t1 = typeof(object);Console.WriteLine(t1.Name);Console.WriteLine(t1.FullName);Console.WriteLine(t1.AssemblyQualifiedName); }執行結果呢?
誠如MSDN所說,Name返回了簡單的類型名稱,FullName包含命名空間,而AssemblyQualifiedName則包含程序集全名稱。而對于非強名稱程序集,其AssemblyQualifiedName依然返回,相關的程序集信息,例如:
Console.WriteLine(t3.AssemblyQualifiedName);Anytao.Learning.ExpressionTree.One, Anytao.Learning.ExpressionTree, Version=1.0.?
0.0, Culture=neutral, PublicKeyToken=null
2.2 向復雜過度
如果我們只把目光停留在簡單類型,那么這三個家伙也不值得花點小時間來注意了,除了簡單,還得復雜。所以,我饒尤其是的把Expression拿來抓丁了:
static void Main(string[] args) {Type t2 = typeof(Expression<Func<int, int>>);Console.WriteLine(t2.Name);Console.WriteLine(t2.FullName);Console.WriteLine(t2.AssemblyQualifiedName); }執行的結果呢?
顯然,對于答案,引起我們關注的是在Expression<Func<int, int>>中,其FullName的Func<int, int>類型,以及int類型均獲取到其AssemblyQualifiedName,而不是FulName。這留給我們一個大大的疑問,對其原因進行一點點深究,我們就可以有這樣的思考,Func<T>以及int分別存在于System.Core和mscorlib程序集,對于我們本身程序集而言,完全有可能在其他引用程序集中引入一個FullName相同的Assembly,所以為唯一限定起見,以AssemblyQualifiedName標示Func<T>和int是完全正確的。
同意的問題,存在于List<T>等其他類型。任何可替換類型參數的實際類型,都可能由不同程序集的加載而變得不夠“唯一”,所以AssemblyQualifiedName來限定List<T>的FullName是明智的。
2.3 順便看看Type.ToString()
Type類型還有一個ToString(),用于返回Type的Name,那么這個Name究竟是這三個中的哪一個呢?如果看了答案,你肯定又一次崩潰:
static void Main(string[] args) {Type t1 = typeof(object);Type t2 = typeof(Expression<Func<int, int>>);Type t3 = typeof(One);Type t4 = typeof(List<int>);Console.WriteLine(t1.ToString());Console.WriteLine(t2.ToString());Console.WriteLine(t3.ToString());Console.WriteLine(t4.ToString()); } 我們看看此時的結果:雖然很無語,Type.ToString()事實上并未返回Name、FullName或者AssemblyQualifiedName,而是不完全的FullName,具體就不做過多陳述了,我們可以由結果看得很明白。
3 回到問題
顯然,FullName在一個程序集中是唯一限定的,包含了所在的命名空間,而AssemblyQualifiedName則更包含其程序集名稱,對于復雜類型的例如List<T>這樣的類型,即便是FullName也將以AssemblyQualifiedName顯示其類型參數,所以對于老趙的方案FullName是完全可以勝任為不同Type實現唯一key值的需求。
你認為呢?
?
支持(0)?反對(0)
??
#3樓?2009-03-18 03:48?飛林沙
呵呵,這么晚了,應該沒人和我搶座位了,第一次先看后頂!?
我感覺微軟是推薦我們去使用FullName作為一個類的完整名字(其中包括泛型的不同版本)...... 而像AssemblyQualifiedName,應該屬于是非主流屬性了吧
支持(0)?反對(0)
??
#4樓?2009-03-18 07:16?Anders Liu
建議應該捎帶著說說命名空間。其實命名空間沒什么大用,無非就是解決同一個程序集里的命名沖突。所以,像類型啊、成員啊什么的,在源數據庫都有自己的表,甚至有的還有不止一張表;而命名空間只是TypeDef的一個列而已。
3樓說得有道理,其實FullName(命名空間+名稱)才是類的完整名字,Name可以看座一個簡寫了。但3樓也不準確,FullName并不是“類的唯一標記”,類的唯一標記應該包括全限定的程序集名稱和類的完整名稱(如System.Object,mscorlib, version=2.0...., culture=nature, publickeytoken=....這樣)。
支持(0)?反對(0)
??
#5樓?2009-03-18 08:15?紫色永恒
又見非主流屬性啊。。
支持(0)?反對(0)
??
#6樓?2009-03-18 09:08?Jeffrey Zhao
@飛林沙?
類的唯一標記難道不是AssemblyQualifiedName嗎?不同Assembly下也可以由namespace+class相同的類型阿
支持(0)?反對(0)
??
#7樓?2009-03-18 09:26?飛林沙
@Jeffrey Zhao?
恩,是我錯了。天真化了,道歉
支持(0)?反對(0)
??
#8樓?2009-03-18 09:27?飛林沙
@Jeffrey Zhao?
修改了
支持(0)?反對(0)
??
#9樓?[樓主]?2009-03-18 10:50?Anytao
@施炯?
呵呵,還不算晚,發表之后準備關機:-)?
這是老習慣了
支持(0)?反對(0)
??
#10樓?[樓主]?2009-03-18 10:51?Anytao
@Jeffrey Zhao?
呵呵,這話言重了,是我佩服你,剛好若干天前關注過這個問題,看到你的文中提到就順便組織組織思路了。?
哈哈:-)
支持(0)?反對(0)
??
#11樓?[樓主]?2009-03-18 10:53?Anytao
@飛林沙?
一般情況下,以FullName進行限定是完全沒有問題的,但是這個非主流的說法,嘿嘿,我就不曉得怎么回答了
支持(0)?反對(0)
??
#12樓?[樓主]?2009-03-18 10:55?Anytao
@Anders Liu?
呵呵,那有時間我就補充補充命名空間,因為和“Name這回事兒”有關系,如果從Metadata的角度去考量,那就更有說道了。?
關于AssemblyQualifiedName,我完全同意你的觀點,這也是List<T>獲取FullName時不能唯一限定而采用AssemblyQualifiedName策略的原因吶:-)
支持(0)?反對(0)
??
#13樓?[樓主]?2009-03-18 10:56?Anytao
@紫色永恒?
今天,第二次聽到“非主流”,哈哈,與時俱進
支持(0)?反對(0)
??
#14樓?[樓主]?2009-03-18 10:56?Anytao
@Jeffrey Zhao?
@飛林沙?
你倆都討論完了,我看看熱鬧就行了
支持(0)?反對(0)
??
#15樓?2009-03-18 11:44?Jeffrey Zhao
@Anytao?
今年是牛年,我們都愛“非主牛”。
支持(0)?反對(0)
??
#16樓?[樓主]?2009-03-18 13:01?Anytao
@Jeffrey Zhao?
哈哈,你指貓撲上的吧:-)
支持(0)?反對(0)
??
#17樓?2009-03-19 08:27?999999999999999
看來有很多細節問題,我都不知道呀
支持(0)?反對(0)
??
#18樓?[樓主]?2009-03-19 10:32?Anytao
@wxws?
嘿嘿,很多細節,也是試過了才知道。
支持(0)?反對(0)
??
#19樓?2009-07-13 16:27?大樹
好文,《你必須知道的.NET》一看一半,收獲頗豐。我想還得繼續文虎而知新,繼續實戰。
支持(0)?反對(0)
??
#20樓?2009-07-13 16:28?大樹
好文,《你必須知道的.NET》已看一半,收獲頗豐。我想還得繼續溫故而知新,繼續實戰。
---------------------
不留神,怎么那么多錯別字呢!
支持(0)?反對(0)
??
#21樓?2009-12-13 20:10?☆用心生活☆
學習了,很受用
支持(0)?反對(0)
??
#22樓?2010-09-11 16:34?cuishengli
是否有這個可能,AssemblyQualifiedName是新增的用于替代fullname的屬性,但是為了兼容舊版本,就保留了fullname。
并且在AssemblyQualifiedName推出之前,發現fullname不唯一的bug,為了趕時間,就把fullname增加限定的內容。
保險起見,并且根據一致性的原則選擇使用AssemblyQualifiedName更好一些。
總結
以上是生活随笔為你收集整理的[你必须知道的.NET]第二十八回:说说Name这回事儿的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 白户如何快速申请信用卡
- 下一篇: 油价上涨下跌谁决定的?一大因素是根本!