[你必須知道的.NET]第二十八回:說說Name這回事兒
[你必須知道的.NET]第二十八回:說說Name這回事兒
發布日期:2009.3.18 作者:Anytao
? 2009 Anytao.com ,原創作品,轉貼請注明作者和出處。
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值的需求。
你認為呢?
2009/03/18 | http://anytao.cnblogs.com/ | http://anytao.net/blog/post/2009/03/17/must_net_28.aspx
本文以“現狀”提供且沒有任何擔保,同時也沒有授予任何權利。 | This posting is provided "AS IS" with no warranties, and confers no rights.
本文版權歸作者所有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利。
溫故知新
[開篇有益]
[第一回:恩怨情仇:is和as]
[第二回:對抽象編程:接口和抽象類]
[第三回:歷史糾葛:特性和屬性]
[第四回:后來居上:class和struct]
[第五回:深入淺出關鍵字---把new說透]
[第六回:深入淺出關鍵字---base和this]
[第七回:品味類型---從通用類型系統開始]
[第八回:品味類型---值類型與引用類型(上)-內存有理]
[第九回:品味類型---值類型與引用類型(中)-規則無邊]
[第十回:品味類型---值類型與引用類型(下)-應用征途]
[第十一回:參數之惑---傳遞的藝術(上)]
[第十二回:參數之惑---傳遞的藝術(下)]
[第十三回:從Hello, world開始認識IL]
[第十四回:認識IL代碼---從開始到現在]
[第十五回:繼承本質論]
[第十六回:深入淺出關鍵字---using全接觸]
[第十七回:貌合神離:覆寫和重載]
[第十八回:對象創建始末(上)]
[第十九回:對象創建始末(下)]
[第二十回:學習方法論]
[第二十一回:認識全面的null]
[第二十二回:字符串駐留(上)---帶著問題思考]
[第二十三回:品味細節,深入.NET的類型構造器]
[第二十四回:認識元數據和IL(上)]
[第二十五回:認識元數據和IL(中)]
[第二十七回:interface到底繼承于object嗎?]
Worktile,新一代簡單好用、體驗極致的團隊協同、項目管理工具,讓你和你的團隊隨時隨地一起工作。完全免費,現在就去了解一下吧。
https://worktile.com

浙公網安備 33010602011771號