Alain
Alain

Reputation: 27220

Are typeof(T) and this.GetType().GetGenericArguments()[0] always equivalent within a generic class instance?

I have a covariantly-safe generic class that wraps another. I wish to make it simple to get the most-derived type available of the instance at run-time:

public interface IReference<out T> { Type UnderlyingType { get; } }

public class Reference<T> : IReference<T> where T : class
{
    public Type UnderlyingType => /*typeof(T)*/ this.GetType().GetGenericArguments()[0];
}

I'm pretty sure in the example above I can just use typeof(T) to make the implementation above faster - but I want to make sure this doesn't lead to cases where a compile-time type is returned that is different from what the run-time type might have been.


For example, if someone goes:

IReference<object> weak = new Reference<string>()
IdentifyReference(weak);

void IdentifyReference<T>(IReference<T> unknown) where T : class {
    Print(typeof(T));
    Print(unknown.UnderlyingType);
}

I want the following output:

object
string

Upvotes: 1

Views: 190

Answers (1)

Sweeper
Sweeper

Reputation: 271355

You can be sure that typeof(T) in the UnderlyingType property produces the runtime type, because of how polymorphism works.

There is simply not enough information at compile time for the compiler to figure out what unknown.UnderlyingType is. Keep in mind that IReference is an interface, so the compiler hasn't got the faintest idea of what concrete type unknown is. Therefore, it doesn't even know that this particular implementation should be executed:

public Type UnderlyingType => typeof(T) /*this.GetType().GetGenericArguments()[0]*/;

As far as the compiler is concerned, it could be an implementation from Foo, which just so happens to implement IReference<object>.

Therefore, the expression typeof(T) is evaluated at runtime, when runtime polymorphism (dynamic dispatch chooses the right implementation) occurs. The way polymorphism works causes the expression to always be evaluated in the context of the runtime type.

Upvotes: 1

Related Questions