C-Type类中NameFullNameNamespaceAssemblyQualifiedName的区别
C# Type类中Name、FullName、Namespace、AssemblyQualifiedName的区别
前言
在C#中,
Type
类提供了多种属性来获取类型的相关信息。以下是
Name
、
FullName
、
Namespace
和
AssemblyQualifiedName
这几个属性的区别和具体用途。
一、获取各名称属性示例
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
的类,并且你想在控制台应用程序中动态加载这个类并调用其方法。
步骤说明
- 定义类库项目
(
MyLibrary.dll
) - 编写控制台应用程序
(
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}");
}
}
}
详细步骤解释
获取
AssemblyQualifiedName
:- 在上面的示例中,
assemblyQualifiedName
包含了完整的类型名称、命名空间、程序集名称及其版本信息。 - 注意:你需要确保程序集名称和版本信息与实际的类库匹配。如果类库是强命名的,还需要包括
PublicKeyToken
。
- 在上面的示例中,
加载类型 :
- 使用
Type.GetType(assemblyQualifiedName)
方法来加载指定的类型。如果类型或程序集找不到,该方法将返回null
。
- 使用
创建实例 :
- 使用
Activator.CreateInstance(myType)
方法创建目标类型的实例。
- 使用
调用方法 :
- 使用
GetMethods()
或GetMethod()
方法获取要调用的方法的信息。 - 使用
Invoke()
方法调用该方法。
- 使用
运行结果
当你运行上述控制台应用程序时,它会输出:
Hello from MyClass!
这表明成功地通过
AssemblyQualifiedName
动态加载了
MyClass
类型,并调用了其
DisplayMessage
方法。
7. 扩展:如何创建强名称程序集
- 详见:
四、汇总
- Name
- 类型的简单名称。
- FullName
- 类型的完全限定名称,包括其命名空间,但不包括程序集。
- Namespace
- 类型所在命名空间的名称。
AssemblyQualifiedName
- 获取类型的程序集限定名,包含类型及其所在程序集的详细信息, 适用于通过反射加载类型 。
这些属性各有用途,选择哪一个取决于你的具体需求。例如,如果你只是想显示类型的名称给用户看,可能只需要
Name
或
FullName
;而如果你需要动态加载类型,则可能需要用到
AssemblyQualifiedName
。
结语
回到目录页:
希望以上内容可以帮助到大家,如文中有不对之处,还请批评指正。