【发布时间】:2016-03-02 15:57:56
【问题描述】:
我遇到了一个意外问题。
我想将具有特殊类型的子类转换为具有泛型类型的父类,但编译器不希望这种情况发生...
这是我的父类:
public abstract class DataSource<T>
{
// Abstract methods and constructor
}
其中一个子类:
public class XlsxDataSource : DataSource<Row>
{
// Overriden methods and constructor
}
以及给出错误的代码:
XlsxDataSource dataSource = new XlsxDataSource();
var dataSources = new Dictionary<long, DataSource<Object>>();
dataSources[dataSource.id] = (DataSource<Object>) dataSource;
如您所见,我有一个Dictionary,它可以包含许多DataSources,无论子类型如何。
但是最后一行给出了下一个编译错误:
Cannot convert type 'EDS.Models.XlsxDataSource' to 'EDS.Models.DataSource<object>'
我不明白为什么,因为XlsxDataSource 是来自DataSource 的孩子,而XlsxDataSource 中的类型明确为Row,这显然是在实现System.Object。
编辑
在我的情况下,协变接口不起作用。
这是我修改后的代码:
public interface IDataSource<T, in T1>
{
List<T> GetAllRows();
List<Object> GetValues(T1 row);
}
抽象类:
public abstract class DataSource<T, T1> : IDataSource<T, T1>
{
public abstract List<T> GetAllRows();
public abstract List<Object> GetValues(T1 row);
}
最后是派生较少的类:
public class XlsxDataSource : DataSource<Row, Row>, IDataSource<Row, Row>
{
public abstract List<Row> GetAllRows();
public abstract List<Object> GetValues(Row row);
}
这是选角:
IDataSource<Object, Object> datasource = (IDataSource<Object, Object>) new XlsxDataSource();
但是将XlsxDataSource 转换为IDataSource 对象会导致InvalidCastException:
Unable to cast object of type 'EDS.Models.XlsxDataSource' to type 'EDS.Models.IDataSource`2[System.Object,System.Object]'.
【问题讨论】:
-
那是因为它不是
DataSource<Object>,而是DataSource<Row>。如果您想要协方差,则必须使用接口而不是类。 -
但是我的
DataSource类中有一个通用构造函数,所以没有冗余代码,这对于接口是不可能的。 -
你仍然可以在接口和子类之间有一个抽象类。只是协方差仅在您使用接口引用时才有效。 msdn.microsoft.com/en-us/library/dd997386.aspx
-
你为什么需要投射?
-
因为否则我无法将
XlsxDataSource对象添加到只接受DataSource<Object>对象的Dictionary...当我尝试时,这是我得到的错误:Cannot implicitly convert type 'EDS.Models.XlsxDataSource' to 'EDS.Models.DataSource<object>'