さて、次のようなコードを想像してください。
private List<ClientItem> ConvertToClientItems(BaseCollection<object> serverItems) {
serverItems.Add(new Buyer());
}
Buyeraは であるため、これはコンパイルする必要がありobjectます。
ただし、 を渡した場合はBaseCollection<Seller>、購入者を販売者のリストに追加しようとしただけです。
したがって、ステートメント
BaseCollection<Seller>のサブタイプですBaseCollection<object>
ジェネリック型が出力位置でのみ使用されるBaseCollectionことが保証されている場合にのみ保持されます。上記のAddの例では、入力位置で使用されます。TT
これを解決するには、次のオプションがあります。
- メソッドを削除する必要があるoutキーワードを追加して、BaseCollection を「共変」にし
Addます。ただし、これにより、コレクションが役に立たなくなる可能性があります。
共変インターフェイスをメソッドに渡します。を読み取る だけでよい場合は、既に共変である をserverItems渡しIEnumerableます (コメントで BaseCollection が既に実装していると述べていますIEnumerable)。
private List<ClientItem> ConvertToClientItems(IEnumerable<object> serverItems) {
// You can only read serverItems here, so we are fine.
}
メソッド自体をジェネリックにする
private List<ClientItem> ConvertToClientItems<T>(BaseCollection<T> serverItems) {
// This also prevents the evil `Add` call, since you'd need to create
// an object of the correct type T first.
}