c# - 在 C# 中对这种行为的解释是什么

标签 c# types clr

考虑这个简单的控制台应用程序:

class Program
{
    static void Main(string[] args)
    {
        var human = CreateHuman(args[0]);
        Console.WriteLine("Created Human");
        Console.ReadLine();
    }

    public static object CreateHuman(string association)
    {
        object human = null;
        if (association == "is-a")
        {
            human = new IsAHuman();
        }
        else
        {
            human = new HasAHuman();
        }
        return human;
    }
}

public class IsAHuman : Human
{
}

public class HasAHuman
{
    public Human Human { get; set; }
}

Human 类在另一个程序集中,比如 HumanAssembly.dll。如果 HumanAssembly.dll 存在于我们的控制台应用程序的 bin 目录中,一切都会好起来的。正如我们所料,删除它会遇到 FileNotFoundException

虽然这部分我不明白。注释human = new IsAHuman();行,重新编译并删除HumanAssembly.dll。在这种情况下,控制台应用程序不会抛出任何异常。

我的猜测是 CLR 编译器区分是一个有一个关联。换句话说,CLR 试图找出并理解并可能加载存在于类定义语句 中的所有类型,但它可以实例化一个类而不知道其中包含什么。但我不确定我的解释。

我找不到很好的解释。对此行为的解释是什么?

最佳答案

您正在看到 JIT 编译器的行为。及时。一个方法直到最后可能的时刻才会被编译,就在它被调用之前。由于您消除了实际构建 Human 对象的需要,因此没有留下强制抖动加载程序集的代码路径。所以你的程序不会崩溃。

最后剩下的对 Human 的引用是 HashAHuman.Human 属性。你不用它。

预测抖动何时需要加载程序集在实践中不是那么简单。当您运行代码的发布版本时,它变得非常难以推理。通常enables the optimizer这是内置在抖动中的,其核心优化策略之一是内联一个方法。为此,它需要在调用之前访问该方法。您需要一个额外的间接级别,一个具有 [MethodImpl(MethodImplOptions.NoInlining)] 属性的额外方法来阻止它进行窥视。这有点深入,始终首先考虑插件架构,例如 MEF。

关于c# - 在 C# 中对这种行为的解释是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25136766/

相关文章:

scala - 如何在 Scala 中进行简单的类型转换?

javascript - Typescript 在构造函数中使用 'this' 类型

.net - 没有为泛型类调用 ICorProfilerCallback::ClassUnloadStarted,即使该类已卸载

.net - JIT 与 NGen - 有什么区别?

c# - 通用运行时?

c# - 属性不从私有(private)字段返回值

c# - Windows Phone 8.1 媒体元素

c++ - C++ 中整数类型的正无穷大和负无穷大

c# - 图像调整大小计算 - 发生了什么?

c# - 计算一个值出现在字典集合中的次数