是否可以添加引用而不加载相关的DLL

时间:2013-08-22 10:42:40

标签: c# .net winforms .net-3.5

我有一个依赖于第三方SDK的Winforms应用程序。我在应用程序中包含了.NET引用,但并不总是需要/使用它。如果我尝试在没有DLL的机器上执行程序,它根本不会打开:它甚至不会进入Main

是否可以有引用但指示它只在需要时加载DLL?

(PDFSharp(我使用的另一个参考)似乎只在调用PdfSharp方法时加载,这让我想知道它是否是我可以控制的东西。)

修改 ...我在Program课程中看不到任何第三方引用,但以下是:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;

namespace MyProgram
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main(string[] args)
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);

            try
            {
                Application.Run(new Main(args));
            }
            catch (Exception Ex)
            {
                MessageBox.Show(Ex.Message, "The program has quit :(", MessageBoxButtons.OK, MessageBoxIcon.Error);

                string TracefileContents = "Please email this file to some@body.com\n\n" + "Exception:\n" + Ex.Message + "\n\nStack trace:\n" + Ex.StackTrace.ToString();

                System.IO.File.WriteAllText("Issue Report " + DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss") + ".dat", TracefileContents);
            }
        }
    }
}

2 个答案:

答案 0 :(得分:1)

.NET会自动执行此操作,默认情况下会按需加载所有内容。

答案 1 :(得分:1)

只有在开始使用程序集中的某些类型时才会加载程序集。只是对程序集的引用不会影响应用程序的运行时行为

为了更准确,CLR仅在JIT编译使用该类型的方法时才加载程序集。这还包括使用派生自/实现程序集的类/接口之一的类型。

即使从另一个程序集实例化具有某种类型的字段或属性的类,也不会强制加载程序集。除非在类的构造函数中访问字段或属性。例如,在其定义语句中设置字段值时:

// `TypeFromAnotherAssembly` is loaded when the class is instantiated
class Test
{
    private TypeFromAnotherAssembly myField = CreateTypeFromAnotherAssembly();
}

编译器在类的构造函数中发出初始化代码。然后,根据上面的规则,当构造函数是JIT编译的(第一次实例化该类)时,CLR加载程序集。这还包括将字段的值设置为null

// `TypeFromAnotherAssembly` is loaded when the class is instantiated
class Test
{
    private TypeFromAnotherAssembly myField = null;
}

当省略初始化语句时,这不会发生,尽管结果完全相同(.NET运行时自动将类字段初始化为null0):

// `TypeFromAnotherAssembly` is NOT loaded when the class is instantiated
class Test
{
    private TypeFromAnotherAssembly myField;
}

你应该注意静态字段的初始化,因为以任何方式访问类都会导致初始化。