gpt4 book ai didi

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

转载 作者:太空宇宙 更新时间:2023-11-03 20:04:00 25 4
gpt4 key购买 nike

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

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/

25 4 0