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