public interface IDic
{
int Id { get; set; }
string Name { get; set; }
}
public class Client : IDic
{
}
Como posso transmitir List<Client>
para List<IDic>
?
public interface IDic
{
int Id { get; set; }
string Name { get; set; }
}
public class Client : IDic
{
}
Como posso transmitir List<Client>
para List<IDic>
?
Respostas:
Você não pode lançá- lo (preservando a identidade de referência) - isso não seria seguro. Por exemplo:
public interface IFruit {}
public class Apple : IFruit {}
public class Banana : IFruit {}
...
List<Apple> apples = new List<Apple>();
List<IFruit> fruit = apples; // Fortunately not allowed
fruit.Add(new Banana());
// Eek - it's a banana!
Apple apple = apples[0];
Agora você pode converter List<Apple>
a IEnumerable<IFruit>
em .NET 4 / C # 4 devido à covariância, mas se quiser, List<IFruit>
terá que criar uma nova lista. Por exemplo:
// In .NET 4, using the covariance of IEnumerable<T>
List<IFruit> fruit = apples.ToList<IFruit>();
// In .NET 3.5
List<IFruit> fruit = apples.Cast<IFruit>().ToList();
Mas isso não é o mesmo que lançar a lista original - porque agora existem duas listas separadas . Isso é seguro, mas você precisa entender que as alterações feitas em uma lista não serão vistas na outra lista. (Modificações nos objetos aos quais as listas se referem serão vistas, é claro.)
List<IFruit>
que era na verdade uma referência a a List<Apple>
. O que você esperaria que acontecesse se adicionasse uma Banana
referência a isso List<IFruit>
?
using
directiva para System.Linq
, ou o que você está tentando chamá-lo, eu não sei como você espera que eu seja capaz de ajudar. Eu sugiro que você faça mais pesquisas e, se ainda estiver preso, faça uma pergunta com um exemplo reproduzível mínimo .
Um iterador Cast e .ToList ():
List<IDic> casted = input.Cast<IDic>().ToList()
vai fazer o truque.
Originalmente, eu disse que a covariância funcionaria - mas, como Jon corretamente apontou; não, não vai!
E originalmente eu também estupidamente à esquerda para fora da ToList()
chamada
Cast
retorna um IEnumerable<T>
, não um List<T>
- e não, a covariância não permitirá essa conversão, porque não seria seguro - veja minha resposta.
ToList()
estava faltando antes de ler seu comentário; mas sim, como você mostrou, claro que a covariância não funcionará! Doh!
Cast
chamada no .NET 4, desde que especifique o argumento de tipo para ToList
.
Eu também tive esse problema e depois de ler a resposta de Jon Skeet, modifiquei meu código de uso List<T>
para uso IEnumerable<T>
. Embora isso não responda à pergunta original do OP de como posso lançar List<Client>
paraList<IDic>
, evita a necessidade de fazê-lo e, portanto, pode ser útil para outras pessoas que enfrentam esse problema. É claro que isso pressupõe que o código que requer o uso de List<IDic>
está sob seu controle.
Por exemplo:
public void ProcessIDic(IEnumerable<IDic> sequence)
{
// Implementation
}
Ao invés de:
public void ProcessIDic(List<IDic> list)
{
// Implementation
}
List<Client> listOfA = new List<Client>();
List<IDic> list = listOfA.Cast<IDic>().ToList();
Só é possível criando novos List<IDic>
e transferindo todos os elementos.
No .Net 3.5, você pode fazer o seguinte:
List<ISomeInterface> interfaceList = new List<ISomeInterface>(list.Cast<ISomeInterface>());
O construtor de List neste caso leva um IEnumerable.
lista, porém, só é conversível para IEnumerable. Mesmo que myObj possa ser conversível em ISomeInterface, o tipo IEnumerable não é conversível em IEnumerable.