我正在尝试使用泛型实现一个辅助方法(C#/ 3.5) 我有一个很好的类结构,基类如下:
public class SomeNiceObject : ObjectBase
{
public string Field1{ get; set; }
}
public class CollectionBase<ObjectBase>()
{
public bool ReadAllFromDatabase();
}
public class SomeNiceObjectCollection : CollectionBase<SomeNiceObject>
{
}
我希望使用如下通用方法来检索收集:
public class DAL
{
public SomeNiceObjectCollection Read()
{
return ReadFromDB<SomeNiceObjectCollection>();
}
T ReadFromDB<T>() where T : CollectionBase<ObjectBase>, new()
{
T col = new T();
col.ReadAllFromDatabase();
return col;
}
}
这不是用
构建的Error 66 The type 'SomeNiceObjectCollection' cannot be used as type parameter 'T' in the generic type or method 'ReadFromDB<T>'. There is no implicit reference conversion from 'SomeNiceObjectCollection' to 'CollectionBase<ObjectBase>'.
SomeNiceObjectCollection对象是一个CollectionBase,确切地说是一个CollectionBase。那我怎么能让它发挥作用呢?
答案 0 :(得分:2)
在C#3.0中,这是不可能的,但是对于具有协方差和逆变的C#和.NET 4.0,这可能是可能的。
考虑一下,您正在获取包含派生对象的集合,并尝试将其暂时视为基础对象的集合。如果允许,则可以将基础对象插入到列表中,该列表不属于派生对象。
这里有一个例子:
List<String> l = new List<String>();
List<Object> o = l;
l.Add(10); // 10 will be boxed to an Object, but it is not a String!
答案 1 :(得分:2)
C#不支持在列表类型之间进行转换(协方差)。
支持此模式的最佳选择是为ReadAllFromDatabase方法引入一个接口,这样您就不依赖于泛型集合:
public class SomeNiceObject : ObjectBase
{
public string Field1{ get; set; }
}
public interface IFromDatabase
{
bool ReadAllFromDatabase();
}
public class CollectionBase<ObjectBase>() : IFromDatabase
{
public bool ReadAllFromDatabase();
}
public class SomeNiceObjectCollection : CollectionBase<SomeNiceObject>
{
}
public class DAL
{
public SomeNiceObjectCollection Read()
{
return ReadFromDB<SomeNiceObjectCollection>();
}
T ReadFromDB<T>() where T : IFromDatabase, new()
{
T col = new T();
col.ReadAllFromDatabase();
return col;
}
}