次のコード セグメントを確認してください。
public interface ICountable { }
public class Counter<T>
where T : ICountable
{
public int Count(IEnumerable<T> items)
{
return 0;
}
public int Count(T Item)
{
return 0;
}
}
public class Counter
{
public int Count<T>(IEnumerable<T> items)
where T : ICountable
{
return 0;
}
public int Count<T>(T Item)
where T : ICountable
{
return 0;
}
}
Counter の 2 つのバージョンは、ジェネリック パラメーターの仕様のみが異なります。1 つはジェネリック型パラメーターとして定義され、もう 1 つはジェネリック引数として定義されます。どちらもメソッド引数を制限して ICountable インターフェイスを実装します。それらをそれぞれ特定および非特定と呼びます。
ここで、 ICountableインターフェイスとインスタンスのコレクションを実装するクラスを定義しています。
public class CItem : ICountable { }
var countables = new List<CItem>();
次に、コレクションで両方の Counter クラスを使用したいと思います。
var specific = new Counter<CItem>();
var nonspecific = new Counter();
specific.Count(countables);
nonspecific.Count(countables);
特定のカウンターは、 countablesコレクションが署名int Count(IEnumerable)に分類される必要があることを認識しますが、非特定のバージョンはそうではありません。エラーが発生します:
型 ' ' は、ジェネリック型またはメソッド ' ' の
System.Collections.Generic.List<CItem>
型パラメーター ' ' として使用できません。' から への暗黙的な参照変換はありません 。T
Counter.Count<T>(T)
List<CItem>
ICountable
特定されていないバージョンがコレクションに間違った署名を使用しているようです。
なぜ彼らは異なる振る舞いをするのですか?他のバージョンと同じように動作するために、特定されていないバージョンをどのように指定できますか?
注: この例が現実的でないことはわかっています。ただし、拡張メソッドを使用した非常に複雑なシナリオでこの問題に直面しました。簡単にするためにこれらのクラスを使用します
前もって感謝します