função genérica em uma lista de classe derivada
Pergunta
Eu sinto a minha pergunta é muito burro, ou outra forma de colocá-lo é: Eu estou muito perdida no meu código para ver uma solução alternativa para agora. Ficar muito tempo em um problema, e sua visão se torna mais estreito e mais estreito> <. Além disso, eu não sou bom o suficiente com herança, polimorfismo e assim
Aqui está a idéia: eu tenho lista múltiplo de classe derivada, e eu gostaria de chamar funções genéricas nessas listas (accesing e modificar os membros da classe base). Sinto que há algo a ver com a herança, mas não conseguem fazê-lo funcionar como eu quero por agora.
Aqui está um exemplo muito simples do que estou pretendendo fazer:
class Baseclass
{
public int ID;
public string Name;
}
class DerivedClass1 : Baseclass
{
}
private void FuncOnBase(List<Baseclass> _collection)
{
// ...
foreach (Baseclass obj in _collection)
{
++obj.ID;
}
// ...
}
private void FuncTest()
{
List<DerivedClass1> collection1 = new List<DerivedClass1>();
collection1.Add(new DerivedClass1() { ID = 1 });
collection1.Add(new DerivedClass1() { ID = 2 });
collection1.Add(new DerivedClass1() { ID = 3 });
FuncOnBase(collection1); // ==> forbidden, cannot convert the derived class list to the base class list
}
Solução
Gotta. A List<DerivedClass1>
é não a List<Baseclass>
-. Caso contrário, FuncOnBase
poderia tentar adicionar um Baseclass
à lista, eo compilador não manchá-lo
Um truque é usar um método genérico:
private void FuncOnBase<T>(List<T> _collection) where T : Baseclass
{
// ...
foreach (T obj in _collection)
{
obj.ID++;
}
// ...
}
Em termos do exemplo I apresentada acima - nota que somos capazes de adicionar um T
à lista; útil, em particular, se adicionarmos a restrição T : new()
, ou passar em (por exemplo) um params T[]
.
Note também que IEnumerable<T>
se torna covariant em C # 4.0 / .NET 4.0, então se você passou em apenas uma IEnumerable<Baseclass>
(em vez de uma lista) que iria funcionar "como é":
private void FuncOnBase(IEnumerable<Baseclass> _collection)
{
///...
}
Outras dicas
Se você está apenas fazendo um foreach
, FuncOnBase(IEnumerable<Baseclass> collection)
declarar, que você pode chamar de FuncTest
assim:
FuncOnBase(collection1.Cast<Baseclass>());
Quando você declarar um método com um parâmetro List<T>
mas apenas usar seus recursos IEnumerable<T>
, você está adicionando restrições de API que não significam nada em seu código.