为什么每次调用该方法时都不执行 Compile() 运行?

Why doesn't Compile() run every time the method is called?

这里是 a code piece from MiscUtil library (作者 Jon Skeet 和 Marc Gravell)

static T Add<T>(T a, T b) {
    //TODO: re-use delegate!
    // declare the parameters
    ParameterExpression paramA = Expression.Parameter(typeof(T), "a"),
        paramB = Expression.Parameter(typeof(T), "b");
    // add the parameters together
    BinaryExpression body = Expression.Add(paramA, paramB);
    // compile it
    Func<T, T, T> add = Expression.Lambda<Func<T, T, T>>(body, paramA, paramB).Compile();
    // call it
    return add(a,b);       
}

它在代码下面说:

Isn't this expensive?

Well, compiling the operators isn't trivial, but the static constructor ensures that we only do this once for each signature.

为什么Func<T, T, T>不是每次调用Add<T>(T a, T b)方法都编译,而是只编译一次?

Here is a code piece from MiscUtil library (by Jon Skeet & Marc Gravell):

没有。它在代码下面这样说:

The actual code makes use of static classes and static constructors to cache the operators efficiently, and uses some shared code in ExpressionUtil to simplify the construction of the various Add, Subtract etc operators - but the theory is the same.

这应该可以回答该代码如何避免每次调用 Compile() 的问题:它不会,而且该页面也没有声明它会调用。

每种类型只有一个静态字段,在它们之间共享。此字段在首次使用之前初始化 (see this old documentation from MSDN)。

If a static constructor (...) exists in the class, execution of the static field initializers occurs immediately prior to executing that static constructor. Otherwise, the static field initializers are executed at an implementation-dependent time prior to the first use of a static field of that class.

所以当你第一次声明并尝试使用SomeType<int,int>时,它的静态字段被初始化了。当您第二次声明并尝试使用 SomeType<int,int> 时,再次创建此字段没有意义。它已经存在!它由 .NET 环境内部管理。语言就是这样设计的。

请注意,SomeType<int,int>SomeType<int,long> 是不同的类型(不同的类型参数),需要单独的静态字段。