Here is a code piece from MiscUtil library (by 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);
}
It says below the code that:
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.
What is the reason behind Func<T, T, T>
doesn't get compiled every time Add<T>(T a, T b)
method is called, but insted only gets compiled once?
There is only one static field per type, it's shared among them. This field is initialized just before first use (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.
So when you declare and try to use SomeType<int,int>
for the first time, its static field is initialized. When you declare and try to use SomeType<int,int>
second time, there is no point in creating this field again. It already exists! It's managed internally by .NET environment. This is how language is designed.
Note that SomeType<int,int>
and SomeType<int,long>
are different types (different type arguments) and need separate static fields.