public interface IDic
{
int Id { get; set; }
string Name { get; set; }
}
public class Client : IDic
{
}
Jak mogę rzucić List<Client>
się List<IDic>
?
public interface IDic
{
int Id { get; set; }
string Name { get; set; }
}
public class Client : IDic
{
}
Jak mogę rzucić List<Client>
się List<IDic>
?
Odpowiedzi:
Nie można rzucać go (zachowując tożsamość odniesienia) - to byłoby niebezpieczne. Na przykład:
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];
Teraz możesz przekonwertować a List<Apple>
na IEnumerable<IFruit>
w .NET 4 / C # 4 ze względu na kowariancję, ale jeśli chcesz List<IFruit>
, musisz utworzyć nową listę. Na przykład:
// 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();
Ale to nie to samo, co przesyłanie oryginalnej listy - ponieważ teraz są dwie oddzielne listy. Jest to bezpieczne, ale musisz zrozumieć, że zmiany wprowadzone na jednej liście nie będą widoczne na drugiej. ( Oczywiście modyfikacje obiektów , do których odnoszą się listy, będą widoczne).
List<IFruit>
które w rzeczywistości było odwołaniem do pliku List<Apple>
. Czego byś się spodziewał, gdybyś dodał Banana
do tego odniesienie List<IFruit>
?
using
dyrektywę System.Linq
lub do czego próbujesz ją wywołać, nie jestem pewien, jak oczekujesz, że będę w stanie pomóc. Proponuję przeprowadzić więcej badań, a jeśli nadal utkniesz, zadaj pytanie z minimalnym powtarzalnym przykładem .
Iterator Cast i .ToList ():
List<IDic> casted = input.Cast<IDic>().ToList()
da rade.
Pierwotnie powiedziałem, że kowariancja zadziała - ale jak słusznie zauważył Jon; nie, nie będzie!
I pierwotnie też głupio przerwałem ToList()
rozmowę
Cast
zwraca IEnumerable<T>
, a nie List<T>
- i nie, kowariancja nie pozwoli na tę konwersję, ponieważ byłaby niebezpieczna - zobacz moją odpowiedź.
ToList()
brakuje go przed przeczytaniem twojego komentarza; ale tak, jak już pokazałeś, oczywiście kowariancja nie zadziała! No!
Cast
wywołania w .NET 4, o ile określisz argument typu na ToList
.
Ja też miałem ten problem i po przeczytaniu odpowiedzi Jona Skeeta zmodyfikowałem kod z using List<T>
do use IEnumerable<T>
. Chociaż nie stanowi to odpowiedzi na pierwotne pytanie OP, jak mogę przesyłać List<Client>
doList<IDic>
, pozwala uniknąć takiej potrzeby, a zatem może być pomocne dla innych osób, które napotkają ten problem. To oczywiście zakłada, że kod, który wymaga użycia, List<IDic>
jest pod Twoją kontrolą.
Na przykład:
public void ProcessIDic(IEnumerable<IDic> sequence)
{
// Implementation
}
Zamiast:
public void ProcessIDic(List<IDic> list)
{
// Implementation
}
List<Client> listOfA = new List<Client>();
List<IDic> list = listOfA.Cast<IDic>().ToList();
Jest to możliwe tylko poprzez tworzenie nowych List<IDic>
i przenoszenie wszystkich elementów.
W .Net 3.5 możesz wykonać następujące czynności:
List<ISomeInterface> interfaceList = new List<ISomeInterface>(list.Cast<ISomeInterface>());
Konstruktor List w tym przypadku przyjmuje IEnumerable.
list, choć można ją zamienić tylko na IEnumerable. Mimo że myObj można przekonwertować na ISomeInterface, typ IEnumerable nie jest konwertowany na IEnumerable.