public interface IDic
{
int Id { get; set; }
string Name { get; set; }
}
public class Client : IDic
{
}
Bagaimana cara mentransmisikan List<Client>
ke List<IDic>
?
Anda tidak dapat mentransmisikannya (mempertahankan identitas referensi) - itu tidak aman. Sebagai contoh:
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];
Sekarang Anda dapat mengonversi a List<Apple>
ke IEnumerable<IFruit>
dalam .NET 4 / C # 4 karena kovarian, tetapi jika Anda menginginkannya, List<IFruit>
Anda harus membuat daftar baru . Sebagai contoh:
// 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();
Tetapi ini tidak sama dengan mentransmisikan daftar aslinya - karena sekarang ada dua daftar terpisah . Ini aman, tetapi Anda perlu memahami bahwa perubahan yang dilakukan pada satu daftar tidak akan terlihat di daftar lainnya. (Modifikasi pada objek yang dirujuk daftar tersebut akan terlihat, tentu saja.)
List<IFruit>
yang sebenarnya merupakan referensi ke aList<Apple>
. Apa yang Anda harapkan terjadi jika Anda menambahkanBanana
referensi untuk ituList<IFruit>
?using
arahannyaSystem.Linq
, atau untuk apa Anda mencoba menyebutnya, saya tidak yakin bagaimana Anda mengharapkan saya dapat membantu. Saya sarankan Anda melakukan lebih banyak riset, dan jika Anda masih buntu, Anda mengajukan pertanyaan dengan contoh minimal yang dapat direproduksi .A Cast iterator dan .ToList ():
List<IDic> casted = input.Cast<IDic>().ToList()
akan melakukan triknya.Awalnya saya mengatakan bahwa kovarian akan berhasil - tetapi seperti yang ditunjukkan Jon dengan benar; tidak tidak akan!
Dan awalnya saya juga dengan bodohnya meninggalkan
ToList()
panggilan itusumber
Cast
mengembalikan sebuahIEnumerable<T>
, bukan aList<T>
- dan tidak, kovarian tidak akan mengizinkan konversi ini, karena tidak aman - lihat jawaban saya.ToList()
ada yang hilang sebelum membaca komentar Anda; tapi ya seperti yang Anda tunjukkan, tentu saja Kovarian tidak akan berhasil! Doh!Cast
panggilan di .NET 4, selama Anda menentukan argumen type untukToList
.Saya juga mengalami masalah ini dan setelah membaca jawaban Jon Skeet saya mengubah kode saya dari
List<T>
use to useIEnumerable<T>
. Meskipun ini tidak menjawab pertanyaan asli OP dari Bagaimana saya dapat menyerahkanList<Client>
keList<IDic>
, itu menghindari kebutuhan untuk melakukannya dan dengan demikian dapat membantu orang lain yang mengalami masalah ini. Ini tentu saja mengasumsikan bahwa kode yang memerlukan penggunaanList<IDic>
berada di bawah kendali Anda.Misalnya:
Dari pada:
sumber
Jika Anda dapat menggunakan LINQ maka Anda dapat melakukan ini ...
sumber
sumber
Ini hanya mungkin dengan membuat baru
List<IDic>
dan mentransfer semua elemen.sumber
Di .Net 3.5, Anda dapat melakukan hal berikut:
Konstruktor untuk Daftar dalam hal ini membutuhkan IEnumerable.
daftar meskipun hanya dapat dikonversi ke IEnumerable. Meskipun myObj dapat dikonversi ke ISomeInterface, tipe IEnumerable tidak dapat dikonversi ke IEnumerable.
sumber