RED MY CLOUDY
PLEASE, USE YOUR BRAIN IF YOU GOT SOMETHING

The Key to using Anonymous Types (Kunci untuk menggunakan Jenis Anonymous)

Labels:
Katakanlah Anda ingin daftar semua pelanggan dari sebuah meja di sebuah ComboBox, dan memperbarui UI berdasarkan mana yang dipilih. To do this we'll need to bring back two fields from the database – the customer's name and the customer's ID. Untuk melakukan hal ini kita harus membawa kembali dua field dari database - nama pelanggan dan ID pelanggan. When a customer is selected we want the ComboBox's SelectedValue property to equal the customer's ID. Ketika seorang pelanggan dipilih kita ingin ComboBox's SelectedValue properti untuk sama dengan ID pelanggan.



Here's some quick code that gets us up and running (using Northwind and LINQ to SQL): Berikut adalah beberapa kode yang cepat membuat kita bangun dan berjalan (menggunakan Northwind dan LINQ to SQL):



Dim db As New NorthwindDataContext Dim db As New NorthwindDataContext

Dim query = From row In db.Customers _ Dim query = Dari deretan Dalam db.Customers _

Select row.CompanyName, row.CustomerID Pilih row.CompanyName, row.CustomerID

ComboBox1.DataSource = query.ToList() ComboBox1.DataSource = query.ToList ()

ComboBox1.DisplayMember = "CompanyName" ComboBox1.DisplayMember = "companyname"

ComboBox1.ValueMember = "CustomerID" ComboBox1.ValueMember = "Pelanggan"

But now let's say your boss looks at the app and says “I want you to add an 'All Customers' option as the first item in the list.” Tapi sekarang katakanlah bos Anda melihat pada app dan berkata "Aku ingin Anda untuk menambahkan 'Semua Pelanggan' pilihan sebagai item pertama dalam daftar." How would you do that? Bagaimana Anda melakukannya? You'd need to insert an anonymous type into an existing sequence of anonymous types, which is tricky given that you can never actually use the type's name. Anda akan perlu untuk memasukkan jenis anonim ke urutan yang sudah ada jenis anonim, yang sulit mengingat bahwa Anda tidak pernah benar-benar menggunakan nama jenis.



Thankfully there's a trick that uses generic parameter inference that allows us to do this (it relies on the fact that the compiler will share (or “unify”) the definition of multiple anonymous types when they have the same number of members, in the same order, of the same type, with the same names, and the same mutability): Untungnya ada trik yang menggunakan parameter generik kesimpulan yang memungkinkan kita untuk melakukan hal ini (hal itu bergantung pada fakta bahwa kompiler akan membagi (atau "menyatukan") definisi dari beberapa jenis anonim ketika mereka memiliki jumlah anggota yang sama, sama ketertiban, dari jenis yang sama, dengan nama yang sama, dan hal berubah-ubah yang sama):



Dim db As New NorthwindDataContext Dim db As New NorthwindDataContext

Dim query = From row In db.Customers _ Dim query = Dari deretan Dalam db.Customers _

Select row.CompanyName, row.CustomerID Pilih row.CompanyName, row.CustomerID

Dim allOption = New With {.CompanyName = "All Customers" , _ Dim allOption = Baru Dengan (. Companyname = "Semua Pelanggan", _

.CustomerID = "-1" } . Pelanggan = "-1")

ComboBox1.DataSource = AddOptionForAll(query, allOption).ToList() ComboBox1.DataSource = AddOptionForAll (query, allOption). ToList ()

ComboBox1.DisplayMember = "CompanyName" ComboBox1.DisplayMember = "companyname"

ComboBox1.ValueMember = "CustomerID" ComboBox1.ValueMember = "Pelanggan"



... ...

Function AddOptionForAll( Of T)( ByVal sequence As IEnumerable( Of T), _ Fungsi AddOptionForAll (Of T) (ByVal urutan Seperti IEnumerable (Of T), _

ByVal allOption As T) As IEnumerable( Of T) AllOption Seperti ByVal T) Sebagai IEnumerable (Of T)

'wrap individual element in an array and then union the two sequences 'membungkus individu elemen dalam array dan kemudian persatuan dua sekuens

Return ( New T() {allOption}).Union(sequence) Return (New T () (allOption)). Union (urutan)

End Function End Function



As long as we have an anonymous type that's compatible with the anonymous type that the query generated, the compiler will determine that sequence and allOption are actually the same type and this should work fine. Selama kita memiliki tipe anonim yang kompatibel dengan tipe anonim yang dihasilkan query, compiler akan menentukan urutan dan allOption sebenarnya tipe yang sama dan hal ini harus dapat bekerja baik.



Ok so let's get to the bug – well in this case spotting it is pretty simple (it doesn't compile J ), but fixing it is tricky (though I've already given two pretty big hints). Ok jadi mari kita pergi ke bug - baik dalam kasus ini bercak itu sangat mudah (hal ini tidak dapat dikompilasi J), tetapi memperbaiki itu sulit (walaupun saya sudah cukup besar diberi dua petunjuk). Here's the text of the compiler error (it's on the line that calls AddOptionForAll): Berikut teks dari kesalahan kompilator (ini ada di baris yang panggilan AddOptionForAll):



Data type(s) of the type parameter(s) in method 'Public Function AddOptionForAll(Of T)(sequence As System.Collections.Generic.IEnumerable(Of T), allOption As T) As System.Collections.Generic.IEnumerable(Of T)' cannot be inferred from these arguments because they do not convert to the same type. Jenis data (s) dari jenis parameter (s) dalam metode 'Public Function AddOptionForAll (Of T) (urutan Sebagai System.Collections.Generic.IEnumerable (Of T), allOption Sebagai T) Sebagai System.Collections.Generic.IEnumerable ( T) 'tidak dapat disimpulkan dari argumen ini karena mereka tidak dikonversi ke tipe yang sama. Specifying the data type(s) explicitly might correct this error. Menentukan tipe data (s) secara eksplisit mungkin benar kesalahan ini.



What's wrong and how do we fix it? Apa yang salah dan bagaimana kita memperbaikinya?

. .



. .



. .



. .



. .



Answer: Jawaban: We actually told the compiler to generate two different anonymous type definitions, and thus it can't unify them because the types really are different. Kami benar-benar mengatakan kepada kompiler untuk menghasilkan dua jenis anonim definisi yang berbeda, dan dengan demikian tidak dapat menyatukan mereka karena sebenarnya jenis berbeda.



From earlier: “…the compiler will share (or “unify”) the definition of multiple anonymous types when they have the same number of members, in the same order, with the same names, and the same mutability ” Dari sebelumnya: "... kompilator akan membagi (atau" menyatukan ") definisi dari beberapa jenis anonim ketika mereka memiliki jumlah anggota yang sama, dalam urutan yang sama, dengan nama yang sama, dan hal berubah-ubah yang sama"



The anonymous type that the query generates will have ReadOnly properties, whereas the anonymous type that we generated (allOption) will have Read/Write properties. Jenis anonim menghasilkan bahwa permintaan akan memiliki sifat readonly, sedangkan tipe anonim yang kita dihasilkan (allOption) akan memiliki Baca / Tulis properti. The fix is to allOption immutable so that its structure will match the result of the query: Cara mengatasinya adalah kekal allOption sehingga strukturnya akan cocok dengan hasil dari query:



Dim allOption = New With { Key .CompanyName = "All Customers" , _ Dim allOption = Baru Dengan (Key. Companyname = "Semua Pelanggan", _

Key .CustomerID = "-1" } Key. Pelanggan = "-1")

The “Key” modifier tells the compiler to make those properties ReadOnly and to override Equals and GetHashCode such that they only consider “Key” properties when deciding if two instances of the same anonymous type are equal. The "Key" pengubah memberitahu compiler untuk membuat properti-properti readonly dan untuk menimpa Setara dan GetHashCode sehingga mereka hanya mempertimbangkan "Key" sifat ketika memutuskan apakah dua contoh anonim dari jenis yang sama adalah sama. (the other hint was in the title J ). (yang lainnya adalah petunjuk dalam judul J). For the query above, the compiler automatically inserts the “Key” modifier - ie what we wrote is exactly equivalent to this: Untuk pertanyaan di atas, compiler secara otomatis memasukkan "Kunci" pengubah - yaitu apa yang kita menulis adalah persis sama dengan ini:



Dim query = From row In db.Customers _ Dim query = Dari deretan Dalam db.Customers _

Select New With { Key row.CompanyName, Key row.CustomerID} Pilih Baru Dengan (Key row.CompanyName, Key row.CustomerID)



So with a simple fix to the allOption line we're now using the same anonymous type definition and everything works fine. Jadi dengan memperbaiki sederhana ke garis allOption kita sekarang menggunakan jenis anonim yang sama definisi dan semuanya bekerja dengan baik.



VB's anonymous type syntax is very flexible and provides three different options: immutable, fully mutable, or partially mutable (ie some fields are ReadOnly while others are not). VB's anonim sintaks jenis ini sangat fleksibel dan memberikan tiga pilihan: tidak berubah, sepenuhnya bisa berubah, atau sebagian bisa berubah (yaitu beberapa field yang readonly sementara yang lain tidak). Even for a simple scenario like adding an option to a list, the better you understand how things work under the covers the easier it'll be to debug problems later J . Bahkan untuk skenario sederhana seperti menambahkan opsi untuk daftar, semakin baik Anda memahami bagaimana hal-hal bekerja di bawah selimut semakin mudah untuk debug akan masalah di kemudian J.
0 comments:

Post a Comment

Follow Gilang_UT on Twitter
Instagram