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 Bananareferans eklerseniz ne olmasını beklersiniz List<IFruit>?
usingiç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
Castdö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!
CastTü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.