简体   繁体   中英

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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM