在 C# 中,GetType().AssemblyQualifiedName
返回一个包含类型完整名称及其所在程序集信息的字符串。这种唯一性使其在以下场景中特别有用:
一、组成部分
完整的程序集限定名格式如下:
"Namespace.TypeName, AssemblyName, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
Namespace.TypeName
:类型的完整名称,包括命名空间。AssemblyName
:定义该类型的程序集名称。Version
:程序集版本号。Culture
:程序集的区域性信息。PublicKeyToken
:程序集的公钥标记,用于强名称程序集。
二、用途
-
类型反射:通过程序集限定名可以在运行时动态加载类型:
Type type = Type.GetType("Namespace.TypeName, AssemblyName, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"); object instance = Activator.CreateInstance(type);
-
序列化与反序列化:某些序列化框架(如JSON.NET)使用程序集限定名来确保类型在不同环境中正确解析。
-
配置文件:在配置文件中指定类型时,使用程序集限定名确保唯一性。
using System;
public class Program
{
public static void Main()
{
// 获取内置类型的程序集限定名
string intAssemblyQualifiedName = typeof(int).AssemblyQualifiedName;
Console.WriteLine("int的程序集限定名:");
Console.WriteLine(intAssemblyQualifiedName);
// 输出: System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
// 获取自定义类型的程序集限定名
MyClass obj = new MyClass();
string myClassAssemblyQualifiedName = obj.GetType().AssemblyQualifiedName;
Console.WriteLine("\nMyClass的程序集限定名:");
Console.WriteLine(myClassAssemblyQualifiedName);
// 输出: YourNamespace.MyClass, YourAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
}
}
public class MyClass
{
// 自定义类
}
注意事项
- 版本依赖性:程序集限定名包含版本信息,这意味着如果程序集版本发生变化,类型名称可能不再匹配。
- 强名称程序集:如果程序集使用了强名称(包含公钥标记),则程序集限定名中会包含
PublicKeyToken
值。 - 动态程序集:对于动态生成的程序集,程序集限定名可能包含特殊标识(如
DynamicAssembly
)。
三、替代方案
如果只需要类型名称而不关心程序集信息,可以使用:
GetType().FullName
:获取类型的完整名称(命名空间 + 类型名)。GetType().Name
:获取类型的简单名称。
这些方法返回的名称不包含程序集信息,适用于不需要唯一标识类型的场景。
四、使用场景
1. 跨程序集的类型反射
当需要在运行时从不同程序集中动态加载类型时,必须使用完整的程序集限定名。例如:
// 通过程序集限定名加载并实例化类型
string typeName = "MyNamespace.MyClass, MyAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null";
Type type = Type.GetType(typeName);
object instance = Activator.CreateInstance(type);
- 典型场景:插件系统、依赖注入框架、ORM 映射。
2. 序列化与反序列化
某些序列化框架(如JSON.NET、BinaryFormatter)使用程序集限定名确保类型在不同环境中正确还原。例如:
// 序列化时保存完整类型信息
string serialized = JsonConvert.SerializeObject(myObject, new JsonSerializerSettings {
TypeNameHandling = TypeNameHandling.All
});
- 注意:版本变更可能导致反序列化失败,需谨慎处理程序集版本。
3. 配置文件中的类型引用
在配置文件(如app.config
)中指定类型时,使用程序集限定名确保唯一性:
<configuration>
<system.web>
<httpModules>
<add name="MyModule" type="MyNamespace.MyHttpModule, MyAssembly" />
</httpModules>
</system.web>
</configuration>
4. 分布式系统中的类型标识
在跨应用程序域、进程或机器的通信中,确保类型正确解析:
// 远程对象传递
[Serializable]
public class RemoteData {
public Type DataType { get; set; } // 可能存储为 AssemblyQualifiedName
}
5. 缓存键生成
当使用类型作为缓存键时,程序集限定名可避免不同程序集同名类型的冲突:
// 使用程序集限定名作为缓存键
string cacheKey = type.GetType().AssemblyQualifiedName;
cache[cacheKey] = expensiveResult;
6. 依赖注入容器注册
某些 IOC 容器需要程序集限定名来解析接口实现:
// 在Autofac中注册类型
builder.RegisterType(Type.GetType("MyNamespace.MyService, MyAssembly"))
.As<IMyService>();
7. 代码生成与动态代理
在生成动态代理(如 AOP 拦截器)时,保存原始类型信息:
// 保存被代理类型的完整名称
proxyType.GetCustomAttributes()
.First(a => a.TypeId.ToString() == "OriginalType, MyAssembly");
8. 插件系统与扩展点
允许外部插件通过配置文件声明类型,框架通过程序集限定名加载:
// 从配置读取插件类型
string pluginTypeName = config["PluginType"];
Type pluginType = Type.GetType(pluginTypeName);
何时避免使用?
- 仅需类型名称时:使用
GetType().FullName
或GetType().Name
更简洁。 - 版本敏感场景:程序集版本变更可能导致类型解析失败。
- 跨平台兼容性:不同运行时(如.NET Framework 与.NET Core)的程序集名称可能不同。
替代方案
Type.FullName
:获取不含程序集信息的完整类型名。Type.Assembly.GetName().Name
:单独获取程序集名称。- 自定义类型映射:使用配置文件或约定映射类型别名与程序集限定名。
通过合理使用AssemblyQualifiedName
,可以在需要强类型标识的场景中确保类型解析的准确性。