2009-09-11 30 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! 
相關問題