さて、次のようなコードを想像してください。
private List<ClientItem> ConvertToClientItems(BaseCollection<object> serverItems) {
serverItems.Add(new Buyer());
}
Buyer
aは であるため、これはコンパイルする必要がありobject
ます。
ただし、 を渡した場合はBaseCollection<Seller>
、購入者を販売者のリストに追加しようとしただけです。
したがって、ステートメント
BaseCollection<Seller>
のサブタイプですBaseCollection<object>
ジェネリック型が出力位置でのみ使用されるBaseCollection
ことが保証されている場合にのみ保持されます。上記のAddの例では、入力位置で使用されます。T
T
これを解決するには、次のオプションがあります。
- メソッドを削除する必要がある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.
}