zoukankan      html  css  js  c++  java
  • [你必须知道的.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值的需求。

    你认为呢?

    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.

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

  • 相关阅读:
    Gradle命令行操作
    Web项目构建
    Java构建
    任务操纵
    mysql 查看当前使用的配置文件my.cnf的方法(推荐)
    mysql命令gruop by报错this is incompatible with sql_mode=only_full_group_by
    Oracle注入速查表
    git 初始化项目操作
    mybatis 一次执行多条SQL MySql+Mybatis+Druid之SqlException:sql injection violation, multi-statement not allow
    文件存储 FileUtil FileBaseDto
  • 原文地址:https://www.cnblogs.com/ShaYeBlog/p/3210019.html
Copyright © 2011-2022 走看看