According to this answer at stackoverflow, the generic type in C# is resolved at runtime.
However, according to this answer, in C#, the generic type is resolved at compile time.
What am I missing here?
In other words, is the type T
resolved at compile time or run time?
Update:
Based on Oded's answer, In a case like this, where the type is a closed concrete type (which means it would be resolved at compile time)
class Program
{
static void Main()
{
var t = new Test<int>();
}
}
public class Test<T>
{
}
will the MSIL have the equivalent of
class Program
{
static void Main()
{
var t = new Test();
}
}
public class Test<int>
{
}
According to this answer at stackoverflow, the generic type in C# is resolved at runtime. However, according to this answer, in C#, the generic type is resolved at compile time.
The where clause in a generic definition specifies constraints on the types that are used as arguments for type parameters in a generic type, method, delegate, or local function. Constraints can specify interfaces, base classes, or require a generic type to be a reference, value, or unmanaged type.
Currently, void is not allowed as a generic parameter for a type or a method, what makes it hard in some cases to implement a common logic for a method, that's why we have Task and Task<T> for instance.
The problem is that the question is not well-posed. Two people are claiming opposite things: that types are "resolved" at runtime and that types are "resolved" at compile time.
Since they are contradicting each other, they must both mean something different by "resolved".
I do not know what it means for a type to be "resolved". I do know however what overload resolution is. When asked to solve an overload resolution problem that does not involve dynamic
, the C# compiler determines which overload to call at compile time, based on the compile time information about the generic type. So for example, if you have:
static void Main()
{
var d = new D();
var p = new P<D>();
p.N(d);//Displays In class B
}
class B
{
public void M()// Note, not virtual
{
Console.WriteLine("In class B");
}
}
class D : B
{
public new void M()// new, not overload
{
Console.WriteLine("In class D");
}
}
class P<T> where T : B
{
public void N(T t)
{
t.M();
}
}
N
always calls B.M
even if P<T>
is instantiated as P<D>
. Why? Because the overload resolution problem that determines what the meaning of t.M
is must be solved when P<T>.N
is compiled, and at that time, the best the compiler knows is that t
must be B
, so it chooses B.M
.
If that's not what you mean by "resolved" then clarify the question.
You are missing the concepts of open and closed generic types.
Essentially, a closed generic type is when you actually specify existing types on a generic parameter/s (or they are inferred by the compiler). For example:
Nullable<int> nulInt;
An open generic type is one where one or more generic type is to be determined during runtime (so, the Nullable<T>
class is an example).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With