public interface IDic
{
int Id { get; set; }
string Name { get; set; }
}
public class Client : IDic
{
}
Nasıl yayın yapabiliyorsa List<Client>
için List<IDic>
?
public interface IDic
{
int Id { get; set; }
string Name { get; set; }
}
public class Client : IDic
{
}
Nasıl yayın yapabiliyorsa List<Client>
için List<IDic>
?
Yanıtlar:
Onu çeviremezsiniz (referans kimliğini koruyarak) - bu güvenli olmaz. Örneğin:
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];
Artık bir dönüştürebilirsiniz List<Apple>
bir etmek IEnumerable<IFruit>
sebebiyle kovaryanslarına .NET 4 / C # 4'te, ancak isterseniz bir List<IFruit>
bir oluşturmak zorundayız yeni liste. Örneğin:
// 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();
Ancak bu, orijinal listeyi yayınlamakla aynı şey değildir - çünkü artık iki ayrı liste var. Bu güvenlidir, ancak tek bir liste üzerinde yapılan değişiklikler olduğunu anlamamız gerekir olmayacak diğer listede görülebilir. ( Listelerin atıfta bulunduğu nesnelerde yapılan değişiklikler elbette görülecektir.)
List<IFruit>
aslında bir List<Apple>
. Buna bir Banana
referans eklerseniz ne olmasını beklersiniz List<IFruit>
?
using
için yönergesini System.Linq
, ya da neden ben emin misin yardım edebilmek için beklemek ne kadar değilim, bunu aramaya çalışıyoruz. Daha fazla araştırma yapmanızı öneririm ve hala takılıp kalırsanız, tekrarlanabilir minimum bir örnekle soru sorarsınız .
Bir Cast yineleyici ve .ToList ():
List<IDic> casted = input.Cast<IDic>().ToList()
hile yapacak.
Başlangıçta kovaryansın işe yarayacağını söyledim - ama Jon'un haklı olarak işaret ettiği gibi; hayır olmayacak!
Ve başlangıçta aptalca ToList()
görüşmeyi de bıraktım
Cast
döner bir IEnumerable<T>
değil, bir List<T>
- ve hayır, kovaryans olmaz o güvensiz olacağından, bu dönüşümü sağlayacak - cevabım bakın.
ToList()
okumadan önce eksik olduğunu fark ettim ; ama evet, sizin de gösterdiğiniz gibi, kovaryans işe yaramayacak! Doh!
Cast
Tür bağımsız değişkenini belirttiğiniz sürece .NET 4'te çağrıya ihtiyacınız olmadığı anlamına geldiğinden kovaryans yine de yardımcı olabilir ToList
.
Ben de bu problemi yaşadım ve Jon Skeet'in cevabını okuduktan sonra kodumu kullanmaktan List<T>
değiştirdim IEnumerable<T>
. Bunun OP'ın orijinal soruya cevap olmamasına rağmen yayınlayabileceğim Nasıl List<Client>
içinList<IDic>
böylece bunu yapmak için gereksinimini ortadan yok ve bu sorunla karşılaştıktan başkalarına yararlı olabilir. Elbette bu, kullanımını gerektiren kodun List<IDic>
sizin kontrolünüz altında olduğunu varsayar .
Örneğin:
public void ProcessIDic(IEnumerable<IDic> sequence)
{
// Implementation
}
Onun yerine:
public void ProcessIDic(List<IDic> list)
{
// Implementation
}
List<Client> listOfA = new List<Client>();
List<IDic> list = listOfA.Cast<IDic>().ToList();
Sadece yeni oluşturmak List<IDic>
ve tüm unsurları aktarmakla mümkündür .
.Net 3.5'te aşağıdakileri yapabilirsiniz:
List<ISomeInterface> interfaceList = new List<ISomeInterface>(list.Cast<ISomeInterface>());
Bu durumda List için yapıcı bir IEnumerable alır.
list olsa da yalnızca IEnumerable'a dönüştürülebilir. Olsa myObj ISomeInterface dönüştürülebilir olabilir tip IEnumerable IEnumerable dönüştürülebilir değildir.