C# 无论实际代码(执行)路径如何,是否加载引用的程序集?

C# 无论实际代码(执行)路径如何,是否加载引用的程序集?,c#,.net,lazy-loading,.net-assembly,C#,.net,Lazy Loading,.net Assembly,在使用程序集中的特定类型之前,不应加载通常引用的程序集。但问题是: 这是一个Winforms应用程序。尽管引用了PresentationFramework.dll和System.Xaml.dll程序集,但不应加载它们,因为下面的代码路径从未执行 bool useAutoHandler = false; if (useAutoHandler) // This is always false so below code is not executed! { var currentAppli

在使用程序集中的特定类型之前,不应加载通常引用的程序集。但问题是:

这是一个Winforms应用程序。尽管引用了PresentationFramework.dll和System.Xaml.dll程序集,但不应加载它们,因为下面的代码路径从未执行

bool useAutoHandler = false;

if (useAutoHandler) // This is always false so below code is not executed!
{
    var currentApplication = typeof(System.Windows.Application).GetProperty("Current");
    if (currentApplication != null)
    {
        var application = currentApplication.GetValue(this, null) as System.Windows.Application;
        if (application != null)
        {
            application.DispatcherUnhandledException += this.DispatcherUnhandledException;
        }
    }
}

当我使用AppDomain.CurrentDomain.GetAssemblys()查询加载的程序集时,我看到正在加载表示框架核心&xaml。关于为什么会出现这种情况,您有什么想法吗?

您正在加载
PresentationFramework.dll
程序集,该程序集位于同一行:
typeof(System.Windows.Application)
,因为您正在静态引用此程序集中包含的类型


如果您在发布模式下编译此代码,编译器可能会优化此代码,并从生成的IL中完全删除此
If
。如果
If
语句的主体是运行时生成的IL的一部分,此时包含此代码的方法将被执行,JIT将需要将其转换为机器代码,并且由于您在此程序集中静态引用了一个类型,因此需要加载相应的程序集。

您正在同一行中加载
PresentationFramework.dll
程序集:
typeof(System.Windows.Application)
因为您正在静态引用此程序集中包含的类型


如果您在发布模式下编译此代码,编译器可能会优化此代码,并从生成的IL中完全删除此
If
。如果
If
语句的主体是运行时生成的IL的一部分,此时包含此代码的方法将被执行,JIT将需要将其转换为机器代码,并且由于您在此程序集中静态引用了一个类型,因此需要加载相应的程序集。

引用的程序集在进入存在引用的方法之前加载到进程内存中

如果将代码更改为以下内容:

private void Foo()
{
  var currentApplication = typeof(System.Windows.Application).GetProperty("Current");
  if (currentApplication != null)
  {
    var application = currentApplication.GetValue(this, null) as    System.Windows.Application;
    if (application != null)
    {
      application.DispatcherUnhandledException += this.DispatcherUnhandledException;
    }
  }
}

public void Bar(bool useAutoHandler)
{
  if (useAutoHandler)
  {
    Foo();
  }
}

然后运行
Bar(false)
不应加载额外的程序集。

引用的程序集在进入存在引用的方法之前加载到进程内存中

如果将代码更改为以下内容:

private void Foo()
{
  var currentApplication = typeof(System.Windows.Application).GetProperty("Current");
  if (currentApplication != null)
  {
    var application = currentApplication.GetValue(this, null) as    System.Windows.Application;
    if (application != null)
    {
      application.DispatcherUnhandledException += this.DispatcherUnhandledException;
    }
  }
}

public void Bar(bool useAutoHandler)
{
  if (useAutoHandler)
  {
    Foo();
  }
}

然后运行
Bar(false)
不应该加载额外的程序集。

那么该代码永远不会执行,因为它被包含在块
if(useAutoHandler){…}
中,其中useAutoHandler总是false@Teoman Soygul,这没关系。您正在使用此程序集静态引用一个类,因此需要将此程序集加载到AppDomain中,以便成功JIT此代码。如果您在发布模式下编译,编译器可能会优化此代码并完全删除此
的主体(如果
),程序集将不会加载。如果是这种情况,即使未执行,使用程序集中任何类型的任何代码路径都会导致程序集加载。稍后我将对此进行测试。快速测试显示,在空控制台应用程序中,如果(true==false){var a=typeof(System.Windows.Application).GetProperties();}
这段代码将导致WindowsBase、System.Xaml和PresentationFramework全部加载。事实证明,在任何执行路径中是否实际实例化或使用了任何类型都无关紧要。不管怎样,它们都会被加载。好吧,代码永远不会执行,因为它被封装在块
if(useAutoHandler){…}
中,其中useAutoHandler总是false@Teoman Soygul,这没关系。您正在使用此程序集静态引用一个类,因此需要将此程序集加载到AppDomain中,以便成功JIT此代码。如果您在发布模式下编译,编译器可能会优化此代码并完全删除此
的主体(如果
),程序集将不会加载。如果是这种情况,即使未执行,使用程序集中任何类型的任何代码路径都会导致程序集加载。稍后我将对此进行测试。快速测试显示,在空控制台应用程序中,如果(true==false){var a=typeof(System.Windows.Application).GetProperties();}
这段代码将导致WindowsBase、System.Xaml和PresentationFramework全部加载。事实证明,在任何执行路径中是否实际实例化或使用了任何类型都无关紧要。不管怎样,它们都会被加载。好吧,你的代码引用了System.Windows.Application,我相信它可以在PresentationFramework.dll中找到,它引用了PresentationCore.dll,所以我可以在你的代码运行时立即看到这两个程序集被加载。我怀疑在代码运行之前发生了很多事情,其中一些是导致程序集加载的原因。System.Windows.Application来自PresentationFramework.dll,必须在编译时知道,因此无论您做什么(如“if”),都将始终加载它。如果您想动态加载程序集,是的,您是对的。代码路径无关紧要,只要引用的程序集是静态引用的,它们就会被加载,而不管实际使用情况如何。好吧,您的代码引用System.Windows.Application,我相信它可以在PresentationFramework.dll中找到,PresentationFramework.dll引用PresentationCore.dll,因此我可以在您的代码运行时立即看到加载的这两个程序集。我怀疑在代码运行之前发生了很多事情,其中一些是导致程序集加载的原因。System.Windows.Application来自PresentationFramework.dll,必须在编译时知道,因此无论您做什么(如“if”),都将始终加载它。如果您想动态加载程序集,是的,您是对的。代码路径无关紧要,只要引用的程序集是静态引用的,那么不管实际使用情况如何,都会加载它们。