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这回事儿相关推荐

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

    说在,开篇之前 很早就有说说Metadata(元数据)和IL(中间语言)的想法了,一直在这篇开始才算脚踏实地的对这两个阶级兄弟投去些细关怀,虽然来得没有<第一回:恩怨情仇:is和as>那么 ...

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

    说在,开篇之前 书接上回:  第二十四回:认识元数据和IL(上), 第二十五回:认识元数据和IL(中) 我们继续. 终于到了,说说元数据和IL在JIT编译时的角色了,虽然两个回合的铺垫未免铺张,但是却 ...

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

    说在,开篇之前 书接上回[第二十四回:认识元数据和IL(上)],我们对PE文件.程序集.托管模块,这些概念与元数据.IL的关系进行了必要的铺垫,同时顺便熟悉了以ILDASM工具进行反编译的基本方法认知 ...

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

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

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

    引言 语言是程序开发者行走江湖的手上利器,各大门派的高手在论坛.博客为了自家门派争吵不已早是技术世界中的亮丽风景,虽多少为刚刚踏入江湖的新手提供了思考的素材,但也同时迷惑了初出茅庐的前行方向. 本文不 ...

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

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

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

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

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

    <你必须知道的.NET>网站 | Anytao技术博客  [你必须知道的.NET]第二十一回:认识全面的null 发布日期:2008.7.31 作者:Anytao © 2008 Anyta ...

  9. [你必须知道的.NET]第二十七回:interface到底继承于object吗?

    <你必须知道的.NET>网站 | Anytao技术博客  [你必须知道的.NET]第二十七回:interface到底继承于object吗? 发布日期:2009.03.05 作者:Anyta ...

最新文章

  1. 函数指针到文本反汇编
  2. Ajax进度条动画制作网址
  3. myEtherWallet在线钱包的使用
  4. 《三国志》生僻人名读法集(zz)
  5. vue + element-ui tab切换
  6. 【信息融合】基于matlab BP神经网络和DS证据理论不确定性信息融合问题【含Matlab源码 2112期】
  7. Linux程序设计第二版练习题(第七章)
  8. 倍福--控制步进电机
  9. 开发一套企业管理软件系统要花费多少钱?
  10. 2022百度大数据开发工程师实习面试经历
  11. HTTP Live Streaming
  12. 【渝粤题库】陕西师范大学900013 心身疾病防治与心理健康
  13. FT5316调试记录
  14. Error in sitecustomize; set PYTHONVERBOSE for traceback: NameError: name 'modules_list' is not defin
  15. 数据结构C++——二叉树的实现
  16. 九、propTypes验证
  17. vue 加载动态图片出错的三种解决方法
  18. 关于echarts生成地图的二三事
  19. 解决iphoneX显示问题的几个css属性
  20. MySQL 查看数据库表容量大小

热门文章

  1. thymeleaf 模板语言简介
  2. Summary Day30
  3. 【4.0】jdbcTemplate
  4. PHP编写命令行脚本和后台运行程序的注意事项
  5. 微软企业库4.1学习笔记(十)企业库的设计
  6. [密码学基础][每个信息安全博士生应该知道的52件事][Bristol52]48.TPM的目的和使用方法
  7. Weak Pair HDU - 5877 树状数组+离散化+DFS遍历
  8. 【发现问题】Java中PrintWriter和BufferedWriter的区别
  9. php全局cors,PHP开启CORS - slagga的个人页面 - OSCHINA - 中文开源技术交流社区
  10. python实现多人聊天udp_python—多任务版udp聊天机器人