目录

C-Type类中NameFullNameNamespaceAssemblyQualifiedName的区别

C# Type类中Name、FullName、Namespace、AssemblyQualifiedName的区别


前言

在C#中, Type 类提供了多种属性来获取类型的相关信息。以下是 NameFullNameNamespaceAssemblyQualifiedName 这几个属性的区别和具体用途。


一、获取各名称属性示例

namespace ReflectionDemo
{
    public class User { }
    internal class Program
    {
        static void Main(string[] args)
        {
            var type = typeof(User);

            Console.WriteLine($"{"Name".PadRight(24)}:{type.Name}");
            Console.WriteLine($"{"FullName".PadRight(24)}:{type.FullName}");
            Console.WriteLine($"{"Namespace".PadRight(24)}:{type.Namespace}");
            Console.WriteLine($"{"AssemblyQualifiedName".PadRight(24)}:{type.AssemblyQualifiedName}");
        }
    }
}

运行结果:

Name                    User
FullName                ReflectionDemo.User
Namespace               ReflectionDemo
AssemblyQualifiedName   ReflectionDemo.User, ReflectionDemo, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null

二、分析属性区别

1. Name 属性

  • 定义
    获取类型的简单名称,即不包含命名空间的类型名称。
  • 示例
    对于一个名为 ReflectionDemo.User 的类, Name 属性将返回 "User"
  • 用途
    当你需要获取类型不带命名空间的名称时使用。

2. FullName 属性

  • 定义
    获取该类型的完全限定名称,包括其命名空间,但不包括程序集。
  • 示例
    对于一个名为 ReflectionDemo.User 的类, FullName 属性将返回 ReflectionDemo.User
  • 用途
    当你需要唯一标识一个类型(在其所在的程序集中)而不关心其所属程序集时使用。

3. Namespace 属性

  • 定义
    获取声明该类型的命名空间。
  • 示例
    对于一个名为 ReflectionDemo.User 的类, Namespace 属性将返回 "ReflectionDemo"
  • 用途
    当你需要知道某个类型属于哪个命名空间时使用,这对于避免命名冲突非常有用。

4. AssemblyQualifiedName 属性

  • 定义
    获取类型的程序集限定名,包括命名空间、程序集名称、版本号、文化信息和公钥标记等。这是类型在程序集中的唯一标识。
  • 示例
    对于一个名为 ReflectionDemo.User 且位于 ReflectionDemo 程序集中的类,

    AssemblyQualifiedName 会返回类似 ReflectionDemo.User, ReflectionDemo, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null 的字符串。

  • 用途
    当你需要加载类型或进行反射操作时,通常需要使用 AssemblyQualifiedName 来精确指定类型的位置和版本信息。这对于 跨程序集识别类型 特别重要。

三、AssemblyQualifiedName 详解

1. 定义

AssemblyQualifiedName 是类型的程序集限定名,是一个字符串,这是类型在程序集中的唯一标识。它不仅包含类型的完全限定名(命名空间 + 类型名称),还包含了程序集的详细信息(如名称、版本、文化、公钥令牌等)。这使得 AssemblyQualifiedName 可以在不同程序集中准确地定位和加载特定类型。

2. 格式

AssemblyQualifiedName 的格式如下:

Namespace.TypeName, AssemblyName, Version=Major.Minor.Build.Revision, Culture=culture, PublicKeyToken=publicKeyToken
  • Namespace.TypeName
    类型的完全限定名(包括命名空间)。
  • AssemblyName
    程序集的名称(不包括扩展名)。
  • Version
    程序集的版本号(例如:1.0.0.0)。
  • Culture
    程序集的文化信息(通常是 “neutral”,除非程序集是特定文化的)。
  • PublicKeyToken
    程序集的公钥令牌,用于验证程序集的发布者身份。

示例MyNamespace.MyClass, MyLibrary, Version=1.0.0.0, Culture=neutral, PublicKeyToken=abcdef1234567890

3. 类型的程序集限定名获取方式

  • 通过Type 实例的 AssemblyQualifiedName 属性获取

    type.AssemblyQualifiedName
  • 通过手动按格式组装定义获取

    string assemblyQualifiedName = "MyNamespace.MyClass, MyLibrary, Version=1.0.0.0, Culture=neutral, PublicKeyToken=abcdef1234567890";

4. 程序集的强名称和弱名称

1)强名称(Strong Name)

强名称是一个程序集的唯一标识符,由以下部分组成:

  • 简单名称 :程序集的文件名(不包括扩展名)。
  • 版本号 :程序集的版本信息(例如:1.0.0.0)。
  • 文化标识 :通常为 “neutral”,除非程序集是特定于某种文化的。
  • 公钥/令牌 :用于验证程序集的发布者身份。公钥令牌是公钥的缩写形式。

强名称确保了程序集的唯一性,并且允许 .NET 运行时加载正确的程序集版本,防止不同版本之间的冲突。强名称通过使用私钥签名生成,并可以通过公钥令牌进行验证。

2)弱名称(Weak Name)

弱名称指的是没有强名称签名的程序集。这种程序集没有版本控制和唯一性的保障,因此不能保证跨应用程序的一致性和安全性。 弱名称的程序集仅包含其文件名和可能的版本信息,但不包含公钥令牌和文化标识等强名称元素

我们创建的一个类库,如果没有特殊操作都属于是是弱名称程序集

5. AssemblyQualifiedName 和程序集的强名称和弱名称的关系

1) 强名称程序集

  • 使用 AssemblyQualifiedName 时,如果程序集具有强名称,则必须包含版本、文化、公钥令牌等信息。
  • 示例: MyNamespace.MyClass, MyLibrary, Version=1.0.0.0, Culture=neutral, PublicKeyToken=abcdef1234567890
  • 这种情况下, AssemblyQualifiedName 可以唯一标识并加载特定版本的程序集中的类型。

2) 弱名称程序集

  • 如果程序集没有强名称,则 AssemblyQualifiedName 中可以省略版本、文化和公钥令牌等信息。
  • 示例: MyNamespace.MyClass, MyLibrary
  • 在这种情况下,程序集的唯一性依赖于其文件名和路径,而不是强名称提供的额外标识信息。

6. AssemblyQualifiedName 的应用

1)应用

AssemblyQualifiedName 作为 Type.GetType 方法的参数,动态加载指定类型。

// 类型的程序集限定名 - 强名称
string assemblyQualifiedName1 = "MyNamespace.MyClass, MyLibrary, Version=1.0.0.0, Culture=neutral, PublicKeyToken=abcdef1234567890";           
var type = Type.GetType(assemblyQualifiedName1);

// 类型的程序集限定名 - 弱名称
string assemblyQualifiedName2 = "MyNamespace.MyClass, MyLibrary";
type = Type.GetType(assemblyQualifiedName2);

2)示例代码

AssemblyQualifiedName 在实际应用中主要用于通过反射加载类型,尤其是在跨程序集的情况下。以下是一个具体的案例,展示如何使用 AssemblyQualifiedName 来动态加载类型并创建实例。

案例背景

假设你有两个项目:一个类库( MyLibrary.dll )和一个控制台应用程序( MyConsoleApp.exe )。类库中定义了一个名为 MyNamespace.MyClass 的类,并且你想在控制台应用程序中动态加载这个类并调用其方法。

步骤说明
  1. 定义类库项目 ( MyLibrary.dll )
  2. 编写控制台应用程序 ( MyConsoleApp.exe ) 使用 AssemblyQualifiedName 动态加载并使用类库中的类型。
类库代码 ( MyLibrary.dll )

首先,我们定义一个简单的类库项目,包含一个类 MyClass

// MyLibrary/MyClass.cs
namespace MyNamespace
{
    public class MyClass
    {
        public void DisplayMessage()
        {
            Console.WriteLine("Hello from MyClass!");
        }
    }
}
控制台应用程序代码 ( MyConsoleApp.exe )

接下来,在控制台应用程序中,我们将使用 AssemblyQualifiedName 来动态加载 MyClass 并调用其方法。

using System;
using System.Reflection;

class Program
{
    static void Main(string[] args)
    {
        // 获取 MyLibrary 中 MyClass 的 AssemblyQualifiedName
        string assemblyQualifiedName = "MyNamespace.MyClass, MyLibrary, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null";

        try
        {
            // 加载包含目标类型的程序集
            Type myType = Type.GetType(assemblyQualifiedName);

            if (myType == null)
            {
                Console.WriteLine("Failed to load type.");
                return;
            }

            // 创建目标类型的实例
            object myInstance = Activator.CreateInstance(myType);

            // 调用 DisplayMessage 方法
            MethodInfo methodInfo = myType.GetMethod("DisplayMessage");
            if (methodInfo != null)
            {
                methodInfo.Invoke(myInstance, null);
            }
            else
            {
                Console.WriteLine("Method not found.");
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine($"An error occurred: {ex.Message}");
        }
    }
}
详细步骤解释
  1. 获取 AssemblyQualifiedName :

    • 在上面的示例中, assemblyQualifiedName 包含了完整的类型名称、命名空间、程序集名称及其版本信息。
    • 注意:你需要确保程序集名称和版本信息与实际的类库匹配。如果类库是强命名的,还需要包括 PublicKeyToken
  2. 加载类型 :

    • 使用 Type.GetType(assemblyQualifiedName) 方法来加载指定的类型。如果类型或程序集找不到,该方法将返回 null
  3. 创建实例 :

    • 使用 Activator.CreateInstance(myType) 方法创建目标类型的实例。
  4. 调用方法 :

    • 使用 GetMethods()GetMethod() 方法获取要调用的方法的信息。
    • 使用 Invoke() 方法调用该方法。
运行结果

当你运行上述控制台应用程序时,它会输出:

Hello from MyClass!

这表明成功地通过 AssemblyQualifiedName 动态加载了 MyClass 类型,并调用了其 DisplayMessage 方法。

7. 扩展:如何创建强名称程序集

  • 详见:

四、汇总

  • Name
    类型的简单名称。
  • FullName
    类型的完全限定名称,包括其命名空间,但不包括程序集。
  • Namespace
    类型所在命名空间的名称。
  • AssemblyQualifiedName
    获取类型的程序集限定名,包含类型及其所在程序集的详细信息, 适用于通过反射加载类型

这些属性各有用途,选择哪一个取决于你的具体需求。例如,如果你只是想显示类型的名称给用户看,可能只需要 NameFullName ;而如果你需要动态加载类型,则可能需要用到 AssemblyQualifiedName


结语

回到目录页:

希望以上内容可以帮助到大家,如文中有不对之处,还请批评指正。