Apakah mungkin untuk membuat tipe anonim mengimplementasikan antarmuka?
Saya punya kode yang ingin saya kerjakan, tetapi tidak tahu bagaimana melakukan ini.
Saya punya beberapa jawaban yang mengatakan tidak, atau membuat kelas yang mengimplementasikan antarmuka membangun contoh baru dari itu. Ini tidak benar-benar ideal, tetapi saya bertanya-tanya apakah ada mekanisme untuk membuat kelas dinamis tipis di atas antarmuka yang akan membuat ini sederhana.
public interface DummyInterface
{
string A { get; }
string B { get; }
}
public class DummySource
{
public string A { get; set; }
public string C { get; set; }
public string D { get; set; }
}
public class Test
{
public void WillThisWork()
{
var source = new DummySource[0];
var values = from value in source
select new
{
A = value.A,
B = value.C + "_" + value.D
};
DoSomethingWithDummyInterface(values);
}
public void DoSomethingWithDummyInterface(IEnumerable<DummyInterface> values)
{
foreach (var value in values)
{
Console.WriteLine("A = '{0}', B = '{1}'", value.A, value.B);
}
}
}
Saya telah menemukan artikel Pembungkus antarmuka dinamis yang menjelaskan satu pendekatan. Apakah ini cara terbaik untuk melakukan ini?
c#
anonymous-types
Nick Randell
sumber
sumber
Jawaban:
Tidak, tipe anonim tidak dapat mengimplementasikan antarmuka. Dari panduan pemrograman C # :
sumber
Meskipun ini mungkin pertanyaan berusia dua tahun, dan sementara jawaban di utas itu semua benar, saya tidak bisa menahan diri untuk memberi tahu Anda bahwa sebenarnya mungkin ada kelas anonim yang mengimplementasikan antarmuka, meskipun itu membutuhkan sedikit kecurangan kreatif untuk sampai ke sana.
Kembali pada tahun 2008 saya menulis penyedia LINQ khusus untuk majikan saya saat itu, dan pada satu titik saya harus bisa memberi tahu kelas anonim "saya" dari yang anonim lainnya, yang berarti meminta mereka mengimplementasikan antarmuka yang dapat saya gunakan untuk mengetikkan centang mereka. Cara kami menyelesaikannya adalah dengan menggunakan aspek (kami menggunakan PostSharp ), untuk menambahkan implementasi antarmuka langsung di IL. Jadi, pada kenyataannya, membiarkan kelas anonim mengimplementasikan antarmuka bisa dilakukan , Anda hanya perlu sedikit membengkokkan aturan untuk sampai ke sana.
sumber
Menggunakan tipe anonim ke antarmuka telah menjadi sesuatu yang saya inginkan untuk sementara waktu, tetapi sayangnya implementasi saat ini memaksa Anda untuk memiliki implementasi antarmuka itu.
Solusi terbaik di sekitarnya adalah memiliki beberapa jenis proxy dinamis yang menciptakan implementasi untuk Anda. Menggunakan proyek LinFu yang luar biasa yang dapat Anda ganti
dengan
sumber
DynamicObject
tipe LinFu?System.Dynamic.DynamicObject
hanya memiliki konstruktor yang dilindungi (setidaknya dalam .NET 4.5).DynamicObject
yang mendahului versi DLRJenis anonim dapat mengimplementasikan antarmuka melalui proxy dinamis.
Saya menulis metode ekstensi di GitHub dan posting blog http://wblo.gs/feE untuk mendukung skenario ini.
Metode ini dapat digunakan seperti ini:
sumber
Tidak; tipe anonim tidak dapat dibuat untuk melakukan apa pun kecuali memiliki beberapa properti. Anda harus membuat tipe Anda sendiri. Saya tidak membaca artikel tertaut secara mendalam, tetapi sepertinya menggunakan Reflection.Emit untuk membuat jenis baru dengan cepat; tetapi jika Anda membatasi diskusi untuk hal-hal dalam C # itu sendiri, Anda tidak dapat melakukan apa yang Anda inginkan.
sumber
Solusi terbaik adalah tidak menggunakan kelas anonim.
Perhatikan bahwa Anda harus memberikan hasil kueri ke jenis antarmuka. Mungkin ada cara yang lebih baik untuk melakukannya, tetapi saya tidak dapat menemukannya.
sumber
values.OfType<IDummyInterface>()
gantinya. Itu hanya mengembalikan objek dalam koleksi Anda yang sebenarnya bisa dilemparkan ke tipe itu. Itu semua tergantung pada apa yang Anda inginkan.Jawaban atas pertanyaan yang diajukan secara spesifik adalah tidak. Tapi apakah Anda sudah melihat kerangka kerja mengejek? Saya menggunakan MOQ tetapi ada jutaan dari mereka di luar sana dan mereka memungkinkan Anda untuk mengimplementasikan / rintisan (sebagian atau sepenuhnya) antarmuka secara online. Misalnya.
sumber
Pilihan lain adalah membuat kelas pelaksana tunggal dan konkret yang mengambil lambdas di konstruktor.
Jika semua yang akan Anda lakukan adalah mengonversi
DummySource
keDummyInterface
, maka akan lebih mudah untuk hanya memiliki satu kelas yang mengambilDummySource
konstruktor dan mengimplementasikan antarmuka.Tapi, jika Anda perlu mengubah banyak jenis
DummyInterface
, ini jauh lebih sedikit pelat ketel.sumber