Pertanyaan Bagaimana mengembalikan IQueryable sebagai IQueryable


saya ada kelas Something yang mengimplementasikan ISomething. Bagaimana saya bisa mengonversi / mentransmisikan dari IQueryable<Something> ke sebuah IQueryable<ISomething>. Ketika saya mencoba untuk mentransmisi, saya dapat mengkompilasi, tetapi hasil dari pemain selalu NULL.

Latar belakang: Alasan saya melakukan ini adalah karena saya Something kelas adalah kelas yang dihasilkan CodeSmith (template PLINQO) yang memiliki dekorasi pemetaan tabel, metode, dll ISomething antarmuka adalah "POCO-style", dalam arti itu bodoh dan hanya mencerminkan sifat-sifat Something kelas. Ini juga ada di ruang nama itu sendiri. Saya melakukan ini jadi saya tidak perlu mereferensikan majelis yang memegang Something kelas dari lapisan layanan saya. Majelis yang memegang Something kelas hanya perlu direferensikan di lapisan repositori saya sekarang.


4
2018-04-06 16:59


asal


Jawaban:


Anda dapat menggunakan metode LINQ Cast

 IQueryable<Something> something = ...
 IQueryable<ISomething> casted = something.Cast<ISomething>();

9
2018-04-06 17:02



Untuk memahami apa yang terjadi di sini, penting untuk melihat ini dari perspektif sistem jenis. Untuk sistem tipe, Something dan ISomething adalah dua jenis yang memiliki hubungan seperti warisan (implementasi tidak persis warisan, tetapi dekat). Tipe generik IQueryable<Something> dan IQueryable<ISomething> tidak memiliki hubungan ini. Mereka adalah dua jenis yang benar-benar berbeda, dan termasuk bagian yang benar-benar berbeda dari pohon warisan (cabang yang termasuk IQueryable) daripada Sesuatu atau ISomething.

Jadi saat casting dari IQuerable<Something> untuk IQueryable<ISomething>, sejauh menyangkut sistem jenis Anda mungkin juga mencoba untuk dilemparkan dari IQueryable<double> untuk IQueryable<IDataRecord>. Hasilnya sama: ia tidak tahu bagaimana membuat konversi itu, dan seterusnya as operator mengembalikan null.

Satu larutan untuk masalah ini (bukan masalah itu sendiri, seperti yang ditunjukkan oleh orang lain) disebut kovarian diimplementasikan dalam C # 4.0. .Net Type Variance memungkinkan sistem tipe untuk memiliki pemahaman terbatas tentang spesialisasi hubungan antara dua jenis yang berbeda yang mengkhususkan jenis generik yang sama, sehingga ketika casting dari satu ke tipe yang lain dapat berbeda (perhatikan kata dasar di sini).

Untuk kode sebelum. Net 4, Anda harus menggunakan sesuatu seperti .Cast<T>() metode penyuluhan. Tapi ini kurang ideal, karena memaksa operasi cor nyata, di mana jenis varians memungkinkan kerangka kerja menggunakan tipe sebenarnya yang sudah ada.


11
2018-04-06 17:12



Ada penjelasan yang sangat bagus tentang masalah Kovarian yang Anda hadapi dalam jawaban untuk ini pertanyaan.


1
2018-04-06 17:05



Bukan bagaimana - melainkan, mengapa:

Kovitas Generik - tautan ini akan membantu menjelaskan:

C # Generic Covariance


0
2018-04-06 17:01