实践记录:Type.GetType()返回值为null的问题

今天在分析问题时遇到使用Type.GetType()一直返回null的情况,于是针对相关情况做了个梳理验证。详情如下:

测试项目的程序集介绍:

Tccc.Reflection.First.SPI:类定义所在的程序集
Tccc.Reflection.Second.SPI:类定义所在的程序集
Tccc.Reflection.Tests:单元测试项目,充当主程序执行。
  • 直接引用了Tccc.Reflection.First.SPI,没有引用Tccc.Reflection.Second.SPI
  • 内部定义了类型:School

测试代码如下:

using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Reflection;

namespace Tccc.Reflection.Tests
{
    /// <summary>
    /// 
    /// </summary>
    public class School
    {
        public string Name { get; set; }
    }

    /// <summary>
    /// Type.GetType()测试场景
    /// </summary>
    [TestClass]
    public class TypeGetTypeTests
    {

        /// <summary>
        /// 
        /// </summary>
        [TestMethod]
        public void GetTypeTest_ClassName()
        {
            Type.GetType("School", true);
            //失败:参数不能仅为类名称
        }

        /// <summary>
        /// 
        /// </summary>
        [TestMethod]
        public void GetTypeTest_NamespaceName()
        {
            Type.GetType("Tccc.Reflection.Tests.School", true);
            //成功,因为School在当前程序集中定义
        }
        /// <summary>
        /// 
        /// </summary>
        [TestMethod]
        public void GetTypeTest_QualifiedName()
        {
            Type.GetType("Tccc.Reflection.First.SPI.UserInfoModel,Tccc.Reflection.First.SPI", true);
            //成功,前提是已经添加了对Tccc.Reflection.First.SPI的引用
        }
        /// <summary>
        /// 
        /// </summary>
        [TestMethod]
        public void GetTypeTest_QualifiedName_OtherLocation()
        {
            Type.GetType("Tccc.Reflection.Second.SPI.UserInfoModel,Tccc.Reflection.Second.SPI", true);
            //失败,因为未添加对Tccc.Reflection.Second.SPI的引用
        }

        [TestMethod]
        public void GetTypeTest_QualifiedName_OtherLocation_Load()
        {
            var loadedAssembly = Assembly.LoadFrom(@"C:\Users\chenz\Downloads\Second.SPI\Tccc.Reflection.Second.SPI.dll");
            Assert.IsNotNull(loadedAssembly);

            Type.GetType("Tccc.Reflection.Second.SPI.UserInfoModel,Tccc.Reflection.Second.SPI", true);
            //net451失败,
            //net3.1成功,
        }
    }
}

知识点:

  • 当目标类型在当前程序集或者系统程序集(mscorlib.dll/System.Private.CoreLib.dll)中,则入参只需要类型命名空间名称即可。
  • 当目标类型在其它程序中,则入参需要程序集限定名,即QualifiedName
  • 在NETFramework和netcore平台,对于程序集所在位置的要求不同。

 

当Type.GetType()返回null时依次检查:

  • 1、参数是否包含类型的命名空间
  • 2、目标类型定义是否在当前程序集中
  • 3、目标类型在外部程序集时,要用带程序集的限定名称,即QualifiedName
  • 4、当程序为netframework应用:要求目标类型所在的程序集在CLR的合法搜索路径中。即便Assembly.LoadFrom()也无效。
  • 5、当程序为netcore应用:要求目标类型所在的程序集在CLR的合法搜索路径中或者通过Assembly.LoadFrom()单独加载。

4、5的验证截图如下:

 

参考资料:

Type.GetType 方法 (System) | Microsoft Docs

posted @ 2022-01-19 17:10  万德福儿  阅读(817)  评论(0编辑  收藏  举报