我写了一个带签名的方法:
private List<ClientItem> ConvertToClientItems(BaseCollection<object> serverItems)
我试图用以下方式调用它:
ConvertToClientItems(approvedSellers);
其中approvedSellers
的类型为BaseCollection<Seller>
- Seller
是我无法控制的类。
这应该不可能吗? Visual Studio向我提出错误,指出它无法将BaseCollection<seller>
强制转换为BaseCollection<object>
。
答案 0 :(得分:2)
好吧,想象看起来像这样的代码:
private List<ClientItem> ConvertToClientItems(BaseCollection<object> serverItems) {
serverItems.Add(new Buyer());
}
这应该编译,因为Buyer
是object
。
但是,如果您传递BaseCollection<Seller>
,则只是尝试将买家添加到卖家列表中。
因此,声明
BaseCollection<Seller>
是BaseCollection<object>
仅在BaseCollection
确保通用类型T
仅用于输出位置时才有效。上面的添加示例会在输入位置使用T
。
要解决此问题,您有以下选择:
Add
方法。但是,这可能会使您的收藏无用。将协变接口传递给方法。如果您只需要读取 serverItems
,请传递一个已经协变的IEnumerable
(并且您在评论中提到BaseCollection已经实现了IEnumerable
):< / p>
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.
}
答案 1 :(得分:1)
在BaseCollection中,你必须使用&#34; out&#34;来进行T协变。关键字。
更多信息http://msdn.microsoft.com/en-us/library/dd233059.aspx。
(IEnumerable有效,因为它是协变的。)
public interface BaseCollection<out T>