Type.GetType(string typeName) returns null !?

本文介绍了如何使用Type.GetType方法从字符串获取类型。讨论了当指定完整限定名称时该方法的行为,包括如何处理泛型类型及如何避免返回null值。

Type.GetType gives us the ability to get type back from a string. We pass a well-written type name string to it, and expect it return that type. Sometimes, to your surprise, it returns null. For example, Type.GetType("System.Data.SqlClient.SqlException").

If the assembly name is specified in the typeName string, Type.GetType() will search inside this assembly only; otherwise, it tries to find one in the caller assembly and then the system assembly (mscorlib.dll). Anything after ',' in the typeName string is treated as assembly name. In previous example, no assembly name was specified; neither the caller nor mscorlib had a type of SqlException, Type.GetType did indeed find nothing in its search. To make it work, we need specify System.Data.dll in typeName. In contrast, Type.GetType("System.Int32") can return type System.Int32 without mentioning mscorlib.dll.

Type.AssemblyQualifiedName is a right way to tell what kind of typeName we should provide. typeof(System.Data.SqlClient.SqlException).AssemblyQualifiedName is "System.Data.SqlClient.SqlException, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089". Type.GetType with this long string will succeed in .NET 2.0.

Note that in .NET, namespace and assembly name are not necessarily related. Type "System.Data.SqlClient.SqlException" is not with System.Data.SqlClient.dll (which does not exist, by the way). The separation is one reason why Type.GetType(typeName) tries not to guess which assembly should be loaded and then searched based on the type's namespace.

Other things good to mention here:

  1. To get back a generic type, the typeName needs be like "System.Collections.Generic.List`1", where the mark is `(grave accent), not '(quotation mark). Writing with the wrong mark will be likely to cause Type.GetType returning null too.
  2. If we prefer throwing exception to returning null, use the overload method Type.GetType(typeName, throwOnError)
  3. More information on this API, please go search MSDN . Yiru also has a further discussion on the type name grammar here .
### 代码功能概述 `RawGenericFactory` 是一个静态类,其中包含一个泛型方法 `Create<T>`。该方法的主要功能是根据传入的类型名称字符串 `typeName`,使用 `Activator.CreateInstance` 动态创建该类型的实例,并将其转换为泛型类型 `T` 后返回。 ### 代码详细分析 - **类的定义**: ```csharp public static class RawGenericFactory ``` 这里定义了一个公共的静态类 `RawGenericFactory`。静态类意味着不能创建该类的实例,并且类中的所有成员都必须是静态的。 - **泛型方法的定义**: ```csharp public static T Create<T>(string typeName) ``` 定义了一个公共的静态泛型方法 `Create<T>`,该方法接受一个字符串类型的参数 `typeName`,表示要创建实例的类型名称。泛型类型参数 `T` 表示返回实例的类型。 - **类型查找与实例创建**: ```csharp return (T)Activator.CreateInstance(Type.GetType(typeName)); ``` - `Type.GetType(typeName)`:尝试根据传入的类型名称字符串 `typeName` 获取对应的 `Type` 对象。如果找不到该类型,将返回 `null`。 - `Activator.CreateInstance`:使用 `Activator` 类的 `CreateInstance` 方法,根据获取到的 `Type` 对象动态创建该类型的实例。 - `(T)`:将创建的实例强制转换为泛型类型 `T` 后返回。 ### 潜在问题与注意事项 - **类型名称的准确性**:`Type.GetType` 方法要求传入的类型名称必须是完全限定名,包括命名空间。如果类型名称不准确,将返回 `null`,导致 `Activator.CreateInstance` 抛出 `NullReferenceException`。 - **异常处理**:代码中没有对可能出现的异常进行处理,例如 `Type.GetType` 返回 `null`、`Activator.CreateInstance` 抛出异常等情况。在实际使用中,建议添加适当的异常处理代码。 - **性能问题**:频繁使用 `Activator.CreateInstance` 进行动态实例创建可能会影响性能,因为它涉及到反射操作。在性能敏感的场景中,建议考虑其他替代方案。 ### 改进建议 ```csharp public static class RawGenericFactory { public static T Create<T>(string typeName) { try { var type = Type.GetType(typeName); if (type == null) { throw new ArgumentException($"Type {typeName} not found."); } return (T)Activator.CreateInstance(type); } catch (Exception ex) { // 记录日志或进行其他处理 Console.WriteLine($"Error creating instance: {ex.Message}"); return default(T); } } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值