17

質問が正しいことを願っていますので、例を挙げましょう。次の一般的なメソッドを想像してください。

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制限します。TBase

[...] 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') 型ではありません。

4

2 に答える 2

23

typeof(whatever)常に type のインスタンスを返しますTypeTypeから派生していませんBase

あなたが欲しいのはこれです:

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

同じように見えるものは次のとおりです。

if(variableOfTypeT is Base)

しかし、それには別の意味があります。
最初のステートメント ( with typeof(Base)) はtrueif Tis のみですBasefalseから派生した任意の型になりますBase
2 番目のステートメント ( variableOfTypeT is Base) は、常にtrueクラス内にあります。これは、から派生したクラスはすべて、その基本クラスのチェックをBase返すためです。true

于 2013-02-13T13:30:01.123 に答える
4

それは継承をチェックする方法ではありません。

typeof(T)はタイプですがSystem.Type、そうではありませんBase。T が Base から派生しているかどうかを確認するには、次のようにIsSubclassOf メソッドを使用する必要があります。

if(typeof(T).IsSubclassOf(typeof(Base))  ... 
于 2013-02-13T13:33:55.213 に答える