1

我正在尝试使用泛型(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。那么我怎样才能让它工作呢?

4

2 回答 2

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!
于 2009-09-11T12:34:42.733 回答
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;          
 }
}
于 2009-09-11T12:36:32.553 回答