为什么VS警告我typeof(T)从来都不是泛型方法中提供的类型,其中类型参数被限制为实现T

本文关键字:类型 类型参数 实现 泛型方法 typeof 警告 VS 为什么 | 更新日期: 2023-09-27 17:58:53

我希望这个问题是正确的,所以让我们给你一个例子。想象一下以下通用方法:

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();
        // ...
    }
}

根据MSDN,关键字where将类型参数T限制为Base类型或从此类继承。

[…]where子句可以包括基类约束,该约束规定类型必须将指定的类作为基类(或是该类本身),才能用作该泛型类型的类型参数。

此外,此代码确实编译:

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

那么,当遵循最后一个代码typeof(T)时,应该返回Base,不是吗?为什么Visual Studio会将此警告打印给我?

警告CS0184:给定的表达式从来都不是提供的("Demo.Base")类型。

为什么VS警告我typeof(T)从来都不是泛型方法中提供的类型,其中类型参数被限制为实现T

typeof(whatever)始终返回类型为Type的实例。CCD_ 8不是从CCD_。

你想要的是:

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

看起来是一样的是:

if(variableOfTypeT is Base)

但这有不同的含义
如果TBase,则第一个语句(具有typeof(Base))仅为true。对于从Base派生的任何类型,它都将是false
第二条语句(variableOfTypeT is Base)在类中始终是true,因为从Base派生的任何类都将返回true以检查其基类。

这不是检查继承的方法。

typeof(T)的类型是System.Type,而不是Base。要查看T是否从Base派生,您应该使用IsSubclassOf方法,如下所示:

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