【问题标题】:C# from loaded Dll call GetType of a static class in the main exeC# 从加载的 Dll 调用主 exe 中静态类的 GetType
【发布时间】:2012-11-29 22:18:28
【问题描述】:

我让main.exe 加载了一个 dll,从加载的 dll 中,我尝试获取主 exe 中定义的静态类,因此 dll 项目中的代码将是:

static class DllClass
{
    static DllClass()
    {
        Assembly assembly = Assembly.GetEntryAssembly(); // line 1
        Type type = assembly.GetType("StaticClass");    //line 2
    }
}

但是,第 2 行给了我以下异常

System.Reflection.TargetInvocationException:调用的目标已抛出异常。 ---> System.TypeInitializationException:类型初始化程序 'DllClass' 抛出异常。 ---> System.TypeInitializationException:类型初始化程序 'DllClass' 抛出异常。 ---> System.NullReferenceException: 对象引用未设置为对象的实例。

我认为这里的问题是静态类 StatisClass 不知何故在运行时找不到并返回 null。

有什么解决办法吗?

【问题讨论】:

    标签: c# exception reflection


    【解决方案1】:

    仅使用以下内容怎么样:

    Type t = typeof(StaticClass) 
    

    也许您因此而收到 NullReferenceException:

    “当托管程序集从非托管应用程序加载时,GetEntryAssembly 方法可以返回空引用(在 Visual Basic 中为 Nothing)。例如,如果非托管应用程序创建用 C# 编写的 COM 组件的实例,则调用从 C# 组件到 GetEntryAssembly 方法返回 null,因为进程的入口点是非托管代码而不是托管程序集。"

    (MSDN,http://msdn.microsoft.com/library/system.reflection.assembly.getentryassembly(v=vs.80).aspx

    => 需要测试:

    if (assembly != null)
    {
     ...
    }
    

    【讨论】:

      【解决方案2】:

      上面的代码只有一个原因:你的assembly变量是NULL。那么什么时候会发生这种情况呢?根据MSDN只有一种情况:

      从非托管应用程序加载托管程序集时,GetEntryAssembly 方法可以返回 NULL。例如,如果非托管应用程序创建用 C# 编写的 COM 组件的实例,则从 C# 组件调用 GetEntryAssembly 方法将返回 NULL,因为进程的入口点是非托管代码而不是托管程序集。

      在这种情况下,@Beachwalker 的答案也不起作用。此外,如果您动态加载类型,代码甚至无法编译。

      【讨论】:

      • 是的,在我再次阅读文档 (+1) 后的第一篇文章之后,同时看到了这个。
      • 嗯,这个dll项目是在Visual Studio 2012 .net 2.0框架上构建的,所以dll代码实际上是托管代码。
      • 所以我终于尝试通过调用 AppDomain.CurrentDomain.GetAssemblies() 从 CurrentDomain 获取程序集,它确实返回了一个非空程序集。
      • 托管您的“DllClass”代码的程序集是否被管理并不重要 - 必须管理启动进程的程序集(您的“main.exe”)。
      【解决方案3】:

      使用反射时,只能使用全名检索类型。 即,包括“命名空间”以及类名。

      因此,将第 2 行更改为如下所示,它将起作用:

      Type type = assembly.GetType("NamespaceName.StaticClass");    //line 2
      

      【讨论】:

      • 基本正确,但是错误的类型标识符会导致对变量“type”的空引用,这意味着代码将在以下行中抛出异常,而不是在“第 2 行”中。 ;-)
      • 我假设您已经知道类型(至少类型是非抽象的)并且不想以空引用结束。否则,使用这种代码毫无意义。
      • 抱歉更改:private MyStaticClass GetMyClass() { string fooClassName = "MyStaticClass"; MyStaticClass sClass = null; try { Type type = Type.GetType(fooClassName); if (type == null) type = Type.GetType("MyNamespace." + fooClassName); if (type != null) { sClass = (MyStaticClass)Activator.CreateInstance(type); } } catch block here... return sClass; }
      • 你误会了。问题指出“但是,第 2 行给了我以下例外”。第 2 行抛出 NullReferenceException,这意味着之前无法加载程序集。他是否知道类型并不重要;-)
      • exe项目中的静态类StaticClass在全局命名空间下,所以我用GetType的方式对吗?
      猜你喜欢
      • 2017-02-16
      • 2011-07-04
      • 2010-09-30
      • 1970-01-01
      • 1970-01-01
      • 2012-04-24
      • 2020-08-26
      • 2023-03-24
      • 1970-01-01
      相关资源
      最近更新 更多