1

署名付きのメソッドを作成しました:

private List<ClientItem> ConvertToClientItems(BaseCollection<object> serverItems)

私は次の方法でそれを呼び出そうとしています:

ConvertToClientItems(approvedSellers);

whereapprovedSellersはタイプですBaseCollection<Seller>-Seller私が制御できないクラスです。

これは可能であるべきではありませんか?Visual Studio が にキャストできないというエラーをスローしていBaseCollection<seller>ますBaseCollection<object>

4

2 に答える 2

2

さて、次のようなコードを想像してください。

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.
    }
    
于 2013-10-11T05:33:43.267 に答える
1

BaseCollection では、「out」キーワードを使用して T を共変にする必要があります。

詳細情報http://msdn.microsoft.com/en-us/library/dd233059.aspx

(IEnumerable は共変であるため機能します。)

public interface BaseCollection<out T>
于 2013-10-11T01:05:18.340 に答える