タイトルどおり、C#4で型否定制約を宣言することは可能ですか?
いいえ-C#にもCLRにもそのような概念はありません。
私の知る限り、それは不可能です。
あなたができることはいくつかのランタイムチェックです:
public bool MyGenericMethod<T>()
{
// if (T is IEnumerable) // don't do this
if (typeof(T).GetInterface("IEnumerable") == null)
return false;
// ...
return true;
}
私は自分がコメントに記載されている同じケースを実装しようとしているのを見つけました:
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>());
}
いいえ、ただし「is」で確認して適切に処理することは可能です...
制約を使用して、使用する型にいくつかのプロパティ/メソッド/ ... 使用したいがあることを確認できます。
一部のプロパティ/メソッドが存在しないことを知る目的がないため、型否定制約を持つジェネリックは意味をなさない使用したくない。
これの用途の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
}
}
もちろん、ランタイムチェックは機能しますが、コンパイル時に型チェックを行うメリットはありません。