web-dev-qa-db-ja.com

T:!IEnumerableの汎用NOT制約

タイトルどおり、C#4で型否定制約を宣言することは可能ですか?

49
Cel

いいえ-C#にもCLRにもそのような概念はありません。

43
Jon Skeet

私の知る限り、それは不可能です。

あなたができることはいくつかのランタイムチェックです:

public bool MyGenericMethod<T>()
{
    // if (T is IEnumerable) // don't do this

    if (typeof(T).GetInterface("IEnumerable") == null)
        return false;

    // ...

    return true;
}
4
Didier Ghys

私は自分がコメントに記載されている同じケースを実装しようとしているのを見つけました:

void doIt<T>(IEnumerable<T> what) { }
void doIt<T>(T whats) { }

I exceptedfirst methodを参照する次のコード:

doIt(new List<T>());

しかし実際に2番目を参照します。

1つの解決策は、次のようなものですcastこのような引数:

doIt(new List<T>().AsEnumerable<T>());

キャストは別のオーバーロードによって非表示にできます:

void doIt<T>(List<T> whats) {
    doIt(whats.AsEnumerable<T>());
}
4
Ricardo Valente

いいえ、ただし「is」で確認して適切に処理することは可能です...

0
Jay

制約を使用して、使用する型にいくつかのプロパティ/メソッド/ ... 使用したいがあることを確認できます。

一部のプロパティ/メソッドが存在しないことを知る目的がないため、型否定制約を持つジェネリックは意味をなさない使用したくない

0
ken2k

これの用途の1つは、オプションタイプです。

public class Option<A,B> 
where A : !B
where B : !A
{
    private readonly A a;
    private readonly B b;

    private Option(){}

    public Option(A a) 
    {
        this.a = a
    }

    public Option(B b)  
    {
        this.b = b
    }
} 

もちろん、ランタイムチェックは機能しますが、コンパイル時に型チェックを行うメリットはありません。

0
David