发布日期: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返回的事实真相:

  1. static void Main(string[] args)
  2. {
  3. Type t1 = typeof(object);
  4. Console.WriteLine(t1.Name);
  5. Console.WriteLine(t1.FullName);
  6. Console.WriteLine(t1.AssemblyQualifiedName);
  7. }

执行结果呢?

诚如MSDN所说,Name返回了简单的类型名称,FullName包含命名空间,而AssemblyQualifiedName则包含程序集全名称。而对于非强名称程序集,其AssemblyQualifiedName依然返回,相关的程序集信息,例如:

  1. Console.WriteLine(t3.AssemblyQualifiedName);

Anytao.Learning.ExpressionTree.One, Anytao.Learning.ExpressionTree, Version=1.0. 
0.0, Culture=neutral, PublicKeyToken=null

2.2 向复杂过度

如果我们只把目光停留在简单类型,那么这三个家伙也不值得花点小时间来注意了,除了简单,还得复杂。所以,我饶尤其是的把Expression拿来抓丁了:

  1. static void Main(string[] args)
  2. {
  3. Type t2 = typeof(Expression<Func<int, int>>);
  4. Console.WriteLine(t2.Name);
  5. Console.WriteLine(t2.FullName);
  6. Console.WriteLine(t2.AssemblyQualifiedName);
  7. }

执行的结果呢?

显然,对于答案,引起我们关注的是在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究竟是这三个中的哪一个呢?如果看了答案,你肯定又一次崩溃:

  1. static void Main(string[] args)
  2. {
  3. Type t1 = typeof(object);
  4. Type t2 = typeof(Expression<Func<int, int>>);
  5. Type t3 = typeof(One);
  6. Type t4 = typeof(List<int>);
  7. Console.WriteLine(t1.ToString());
  8. Console.WriteLine(t2.ToString());
  9. Console.WriteLine(t3.ToString());
  10. Console.WriteLine(t4.ToString());
  11. }
  1. 我们看看此时的结果:

虽然很无语,Type.ToString()事实上并未返回Name、FullName或者AssemblyQualifiedName,而是不完全的FullName,具体就不做过多陈述了,我们可以由结果看得很明白。

3 回到问题

显然,FullName在一个程序集中是唯一限定的,包含了所在的命名空间,而AssemblyQualifiedName则更包含其程序集名称,对于复杂类型的例如List<T>这样的类型,即便是FullName也将以AssemblyQualifiedName显示其类型参数,所以对于老赵的方案FullName是完全可以胜任为不同Type实现唯一key值的需求。

你认为呢?

anytao | © 2009 Anytao.com

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.

本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

[你必须知道的.NET]第二十八回:说说Name这回事儿的更多相关文章

  1. [你必须知道的.NET]第二十四回:认识元数据和IL(上)

    发布日期:2009.02.24 作者:Anytao © 2009 Anytao.com ,Anytao原创作品,转贴请注明作者和出处. 说在,开篇之前 很早就有说说Metadata(元数据)和IL(中 ...

  2. [你必须知道的.NET]第二十六回:认识元数据和IL(下)

    发布日期:2009.03.04 作者:Anytao © 2009 Anytao.com ,Anytao原创作品,转贴请注明作者和出处. 说在,开篇之前 书接上回: 第二十四回:认识元数据和IL(上), ...

  3. [你必须知道的.NET]第二十五回:认识元数据和IL(中)

    发布日期:2009.02.25 作者:Anytao © 2009 Anytao.com ,Anytao原创作品,转贴请注明作者和出处. 说在,开篇之前 书接上回[第二十四回:认识元数据和IL(上)], ...

  4. [你必须知道的.NET]第二十九回:.NET十年(上)

    发布日期:2009.05.08 作者:Anytao © 2009 Anytao.com ,Anytao原创作品,转贴请注明作者和出处. /// <summary> /// 本文部分内容,已 ...

  5. [你必须知道的.NET]第二十二回:字符串驻留(上)---带着问题思考

    发布日期:2008.8.27 作者:Anytao © 2008 Anytao.com ,Anytao原创作品,转贴请注明作者和出处. 说在,开篇之前 走钢丝的人,在刺激中体验快感.带着问题思考,在问题 ...

  6. [你必须知道的.NET]第二十回:学习方法论

    说在,开篇之前 本文,源自我回答刚毕业朋友关于.NET学习疑惑的回复邮件. 本文,其实早计划在<你必须知道的.NET>写作之初的后记部分,但是因为个中原因未能如愿,算是补上本书的遗憾之一. ...

  7. [你必须知道的.NET]第十八回:对象创建始末(上)

    本文将介绍以下内容: 对象的创建过程 内存分配分析 内存布局研究 1. 引言 了解.NET的内存管理机制,首先应该从内存分配开始,也就是对象的创建环节.对象的创建,是个复杂的过程,主要包括内存分配和初 ...

  8. [你必须知道的.NET]第二十三回:品味细节,深入.NET的类型构造器

    发布日期:2008.11.2 作者:Anytao © 2008 Anytao.com ,Anytao原创作品,转贴请注明作者和出处. 说在,开篇之前 今天Artech兄在<关于Type Init ...

  9. [你必须知道的.NET]第二十一回:认识全面的null

    发布日期:2008.7.31 作者:Anytao © 2008 Anytao.com ,Anytao原创作品,转贴请注明作者和出处. 说在,开篇之前 null.nullable.??运算符.null ...

随机推荐

  1. ubuntu启动脚本

    下午分析了一下mysql的启动脚本,找到这篇,记录一下,目前很多服务都是以这种方式封装,后面自己写来借鉴一下 http://blog.fens.me/linux-upstart/

  2. bzoj 3212 Pku3468 A Simple Problem with Integers 线段树基本操作

    Pku3468 A Simple Problem with Integers Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 2173  Solved:  ...

  3. bzoj 4069 [Apio2015]巴厘岛的雕塑 dp

    [Apio2015]巴厘岛的雕塑 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 494  Solved: 238[Submit][Status][Dis ...

  4. try catch finally 和return

    结论:1.不管有木有出现异常,finally块中代码都会执行:2.当try和catch中有return时,finally仍然会执行:3.finally是在return后面的表达式运算后执行的(此时并没 ...

  5. 这个随笔用用来放一些好的思想和思考方式(暂时secret)

    一: 给你一个只有4和7的数字,求这是第几个幸运数字? 思路: 我们把4映射成0,7映射成1,然后就如下枚举:0,1,00,01,10,11.因为是映射的,所以可以前导0,然后我们就会知道给出的那个数 ...

  6. C# 生成系统唯一号

    生成唯一号:思路,根据yymmddhhmmss+自增长号+唯一服务器号( SystemNo)生成唯一码,总长度19,例如:1509281204550000101. public class Uniqu ...

  7. Parallel

    介绍 C# 4.0 的新特性之并行运算 Parallel.For - for 循环的并行运算 Parallel.ForEach - foreach 循环的并行运算 Parallel.Invoke - ...

  8. 【poj1901-求区间第k大值(带修改)】树状数组套主席树

    901: Zju2112 Dynamic Rankings Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 7025  Solved: 2925[Sub ...

  9. 边绘边理解prototype跟__proto__

    网上流传着一张讲解prototype跟__proto__关系的图,尽管他已经描绘的很清楚了,但对于初学者来说,江太公感觉还是过于纠结,于是起心重绘,让他们之间的关系更加明晰可理解,一方面出于分享目的, ...

  10. PKUWC 2019 自闭记

    PKUWC 2019 自闭记 Day -1 考前天天在隔壁的物竞教室划水(雀魂,能和吉老师一起玩的游戏都是好游戏),没有做题. Day 0 早上8:16的高铁,到广州南居然要6个小时...不知道福州和 ...