简体   繁体   中英

Why does VS warn me that typeof(T) is never the provided type in a generic method where the type parameter is restricted to implement T?

I hope the question is correct, so let's give you an example. Imagine the following generic method:

public abstract class Base : IDisposable
{
    public static IEnumerable<T> GetList<T>()
        where T : Base
    {
        // To ensure T inherits from Base.
        if (typeof(T) is Base)
            throw new NotSupportedException();

        // ...
    }
}

According to the MSDN the keyword where restricts the type parameter T to be of type Base or to inherit from this class.

[...] a where clause can include a base class constraint, which states that a type must have the specified class as a base class (or be that class itself) in order to be used as a type argument for that generic type.

Also this code does compile:

public static T GetFirst()
    where T : Base
{
    // Call GetList explicitly using Base as type parameter.
    return (T)GetList<Base>().First();
}

So when following the last code typeof(T) should return Base , shouldn't it? Why does Visual Studio then prints this warning to me?

warning CS0184: The given expression is never of the provided ('Demo.Base') type.

typeof(whatever) always returns an instance of type Type . Type doesn't derive from Base .

What you want is this:

if(typeof(T) == typeof(Base))
    throw new NotSupportedException("Please specify a type derived from Base");

Something that looks like it is the same is this:

if(variableOfTypeT is Base)

But that has a different meaning.
The first statement (with typeof(Base) ) only is true if T is Base . It will be false for any type derived from Base .
The second statement ( variableOfTypeT is Base ) is always true in your class, because any class derived from Base will return true for a check for its base class.

That's not how you check inheritance.

typeof(T) is of type System.Type , it's not Base . To see if T is derived from Base you should use the IsSubclassOf method , like this:

if(typeof(T).IsSubclassOf(typeof(Base))  ... 

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