2009-09-11 5 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 Allready реализован интерфейс, который мне нужен, поэтому я изменил ReadFromDB . Благодаря! – edosoft

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! 
Смежные вопросы