public interface IDic
{
int Id { get; set; }
string Name { get; set; }
}
public class Client : IDic
{
}
Jak mogę rzucić List<Client>
się List<IDic>
?
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 plikuList<Apple>
. Czego byś się spodziewał, gdybyś dodałBanana
do tego odniesienieList<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ęźródło
Cast
zwracaIEnumerable<T>
, a nieList<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 naToList
.Ja też miałem ten problem i po przeczytaniu odpowiedzi Jona Skeeta zmodyfikowałem kod z using
List<T>
do useIEnumerable<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:
Zamiast:
źródło
Jeśli możesz używać LINQ, możesz to zrobić ...
źródło
źródło
Jest to możliwe tylko poprzez tworzenie nowych
List<IDic>
i przenoszenie wszystkich elementów.źródło
W .Net 3.5 możesz wykonać następujące czynności:
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.
źródło