C# 在泛型函数中将基础对象用作参数
我正在尝试使用泛型C/3.5实现一个助手方法 我有一个很好的类结构,基类如下:C# 在泛型函数中将基础对象用作参数,c#,generics,base-class,C#,Generics,Base Class,我正在尝试使用泛型C/3.5实现一个助手方法 我有一个很好的类结构,基类如下: public class SomeNiceObject : ObjectBase { public string Field1{ get; set; } } public class CollectionBase<ObjectBase>() { public bool ReadAllFromDatabase(); } public class SomeNiceObjectCollection
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。那么我如何才能让它工作呢?在C3.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!
在C3.0中这是不可能的,但是在C和.NET4.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!
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;
}
}
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;
}
}
Excellence.CollectionBase allready实现了我需要的接口,因此我更改了ReadFromDB。谢谢Excellence.CollectionBase allready实现了我需要的接口,因此我更改了ReadFromDB。谢谢