2009-09-11 54 views
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。那么我如何才能使这个工作?

回答

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;   
} 
} 
+0

Excellent.CollectionBase媒体链接实现的,我需要一个接口,所以我更改了ReadFromDB 。谢谢! – edosoft 2009-09-11 12:52:13

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! 
相关问题