Névtelen típusok (Visual Basic)

A Visual Basic támogatja a névtelen típusokat, amelyek lehetővé teszik objektumok létrehozását anélkül, hogy osztálydefiníciót írnál az adattípushoz. Ehelyett a fordító létrehoz egy osztályt. Az osztály nem rendelkezik használható névvel, közvetlenül az objektumtól Objectörököl, és tartalmazza az objektum deklarálásában megadott tulajdonságokat. Mivel az adattípus neve nincs megadva, névtelen típusnak nevezzük.

Az alábbi példa egy névtelen típusú változót product deklarál és hoz létre, amely két tulajdonsággal NamePriceés .

' Variable product is an instance of a simple anonymous type.
Dim product = New With {Key .Name = "paperclips", .Price = 1.29}

A lekérdezési kifejezések névtelen típusok használatával egyesítik a lekérdezés által kiválasztott adatoszlopokat. Előre nem határozhatja meg az eredmény típusát, mert nem tudja előre jelezni azokat az oszlopokat, amelyekkel egy adott lekérdezés kiválasztható. A névtelen típusok lehetővé teszik olyan lekérdezések írását, amelyek tetszőleges számú oszlopot választanak ki tetszőleges sorrendben. A fordító létrehoz egy adattípust, amely megfelel a megadott tulajdonságoknak és a megadott sorrendnek.

Az alábbi példákban products a termékobjektumok listája látható, amelyek mindegyike számos tulajdonsággal rendelkezik. A változó namePriceQuery egy olyan lekérdezés definícióját tartalmazza, amely a végrehajtáskor egy névtelen típusú példányok gyűjteményét adja vissza, amely két tulajdonsággal rendelkezik, Name és Price.

Dim namePriceQuery = From prod In products
                     Select prod.Name, prod.Price

A változó nameQuantityQuery egy olyan lekérdezés definícióját tartalmazza, amely a végrehajtáskor egy névtelen típusú példányok gyűjteményét adja vissza, amely két tulajdonsággal rendelkezik, Name és OnHand.

Dim nameQuantityQuery = From prod In products
                        Select prod.Name, prod.OnHand

A fordító által névtelen típushoz létrehozott kódról további információt a Névtelen típusdefiníció című témakörben talál.

Figyelemfelhívás

A névtelen típus neve fordítóként jön létre, és fordítástól fordításig változhat. A kód nem használhatja vagy nem támaszkodhat névtelen típus nevére, mert előfordulhat, hogy a név megváltozik egy projekt újrafordításakor.

Névtelen típus deklarálása

Egy névtelen típusú példány deklarációja inicializáló listát használ a típus tulajdonságainak megadásához. Csak akkor adhat meg tulajdonságokat, ha névtelen típust deklarál, más osztályelemeket, például metódusokat vagy eseményeket nem. Az alábbi példában egy névtelen típus egy példánya, product1 amely két tulajdonsággal rendelkezik: Name és Price.

' Variable product1 is an instance of a simple anonymous type.
Dim product1 = New With {.Name = "paperclips", .Price = 1.29}
' -or-
' product2 is an instance of an anonymous type with key properties.
Dim product2 = New With {Key .Name = "paperclips", Key .Price = 1.29}

Ha a tulajdonságokat kulcstulajdonságként jelöli meg, azokkal összehasonlíthat két névtelen típuspéldányt az egyenlőség érdekében. A kulcstulajdonságok értékei azonban nem módosíthatók. További információkért tekintse meg a témakör későbbi, Kulcstulajdonságok szakaszát.

Figyelje meg, hogy egy névtelen típusú példány deklarálása olyan, mintha egy elnevezett típusú példányt deklarál egy objektum inicializáló használatával:

' Variable product3 is an instance of a class named Product.
Dim product3 = New Product With {.Name = "paperclips", .Price = 1.29}

További információ a névtelen típustulajdonságok megadásának egyéb módjairól: A tulajdonságnevek és -típusok következtetése a névtelen típusdeklarációkban.

Kulcstulajdonságok

A kulcstulajdonságok számos alapvető módon különböznek a nem kulcstulajdonságoktól:

  • A rendszer csak a kulcstulajdonságok értékeit hasonlítja össze annak megállapításához, hogy két példány egyenlő-e.

  • A kulcstulajdonságok értékei írásvédettek, és nem módosíthatók.

  • Névtelen típus esetén csak a kulcstulajdonságértékek szerepelnek a fordító által létrehozott kivonatkód-algoritmusban.

Egyenlőség

A névtelen típusok példányai csak akkor lehetnek egyenlők, ha azonos névtelen típusú példányok. A fordító két példányt azonos típusú példányként kezel, ha megfelelnek a következő feltételeknek:

  • Ezek ugyanabban a szerelvényben vannak deklarálva.

  • A tulajdonságok neve megegyezik, ugyanazok a kikövetkeztetett típusok, és ugyanabban a sorrendben vannak deklarálva. A név-összehasonlítások nem megkülönböztetik a kis- és nagybetűket.

  • Az egyes tulajdonságok kulcstulajdonságként vannak megjelölve.

  • Minden deklarációban legalább egy tulajdonság egy kulcstulajdonság.

A kulcstulajdonságokkal nem rendelkező névtelen típusok példánya csak önmagával egyenlő.

' prod1 and prod2 have no key values.
Dim prod1 = New With {.Name = "paperclips", .Price = 1.29}
Dim prod2 = New With {.Name = "paperclips", .Price = 1.29}

' The following line displays False, because prod1 and prod2 have no
' key properties.
Console.WriteLine(prod1.Equals(prod2))

' The following statement displays True because prod1 is equal to itself.
Console.WriteLine(prod1.Equals(prod1))

Két azonos névtelen típusú példány egyenlő, ha a kulcstulajdonságok értéke egyenlő. Az alábbi példák az egyenlőség tesztelését szemléltetik.

Dim prod3 = New With {Key .Name = "paperclips", Key .Price = 1.29}
Dim prod4 = New With {Key .Name = "paperclips", Key .Price = 1.29}
' The following line displays True, because prod3 and prod4 are
' instances of the same anonymous type, and the values of their
' key properties are equal.
Console.WriteLine(prod3.Equals(prod4))

Dim prod5 = New With {Key .Name = "paperclips", Key .Price = 1.29}
Dim prod6 = New With {Key .Name = "paperclips", Key .Price = 1.29,
                      .OnHand = 423}
' The following line displays False, because prod5 and prod6 do not 
' have the same properties.
Console.WriteLine(prod5.Equals(prod6))

Dim prod7 = New With {Key .Name = "paperclips", Key .Price = 1.29,
                      .OnHand = 24}
Dim prod8 = New With {Key .Name = "paperclips", Key .Price = 1.29,
                      .OnHand = 423}
' The following line displays True, because prod7 and prod8 are
' instances of the same anonymous type, and the values of their
' key properties are equal. The equality check does not compare the
' values of the non-key field.
Console.WriteLine(prod7.Equals(prod8))

Írásvédett értékek

A kulcstulajdonságok értékei nem módosíthatók. Az előző példában prod8 például a mezők és Price a Name mezők, de OnHand módosíthatókread-only.

' The following statement will not compile, because Name is a key
' property and its value cannot be changed.
' prod8.Name = "clamps"

' OnHand is not a Key property. Its value can be changed.
prod8.OnHand = 22

Névtelen típusok lekérdezési kifejezésekből

A lekérdezési kifejezésekhez nem mindig szükséges névtelen típusok létrehozása. Ha lehetséges, egy meglévő típust használnak az oszlopadatok tárolására. Ez akkor fordul elő, ha a lekérdezés teljes rekordokat ad vissza az adatforrásból, vagy csak egy mezőt minden rekordból. Az alábbi példakód egy customers osztály objektumgyűjteménye Customer . Az osztály számos tulajdonsággal rendelkezik, és egy vagy több is szerepelhet a lekérdezés eredményében, bármilyen sorrendben. Az első két példában nincs szükség névtelen típusra, mert a lekérdezések nevesített típusok elemeit választják ki:

  • custs1 sztringgyűjteményt tartalmaz, mivel cust.Name ez egy sztring.

    Dim custs1 = From cust In customers
                 Select cust.Name
    
  • custs2 objektumgyűjteményt Customer tartalmaz, mivel minden elem customers egy Customer objektum, és az egész elemet a lekérdezés választja ki.

    Dim custs2 = From cust In customers
                 Select cust
    

A megfelelő névvel ellátott típusok azonban nem mindig érhetők el. Előfordulhat, hogy az ügyfélneveket és címeket egy célra, az ügyfél-azonosítószámokat és a másik helyeket, valamint egy harmadik ügyfélneveket, címeket és rendelési előzményeket szeretné kiválasztani. A névtelen típusok lehetővé teszik a tulajdonságok tetszőleges kombinációjának bármilyen sorrendben történő kiválasztását anélkül, hogy egy új elnevezett típust deklarálhat az eredmény tárolásához. Ehelyett a fordító névtelen típust hoz létre minden egyes tulajdonság-összeállításhoz. Az alábbi lekérdezés csak az ügyfél nevét és azonosítószámát választja ki az egyes Customer objektumok közül.customers Ezért a fordító létrehoz egy névtelen típust, amely csak ezt a két tulajdonságot tartalmazza.

Dim custs3 = From cust In customers
             Select cust.Name, cust.ID

A névtelen típusban lévő tulajdonságok neve és adattípusa egyaránt az argumentumok Selectés a . cust.Namecust.ID A lekérdezés által létrehozott névtelen típusú tulajdonságok mindig kulcstulajdonságok. Amikor custs3 a rendszer a következő For Each ciklusban hajtja végre, az eredmény egy névtelen típusú példányok gyűjteménye, két kulcstulajdonság NameIDés .

For Each selectedCust In custs3
    Console.WriteLine(selectedCust.ID & ": " & selectedCust.Name)
Next

A gyűjtemény custs3 elemei erősen be vannak állítva, és az IntelliSense használatával navigálhat a rendelkezésre álló tulajdonságok között, és ellenőrizheti azok típusait.

További információ: Bevezetés a LINQ használatába a Visual Basicben.

Annak eldöntése, hogy használjon-e névtelen típusokat

Mielőtt létrehoz egy objektumot egy névtelen osztály példányaként, gondolja át, hogy ez-e a legjobb megoldás. Ha például egy ideiglenes objektumot szeretne létrehozni, amely kapcsolódó adatokat tartalmaz, és nincs szüksége más mezőkre és metódusokra, amelyeket egy teljes osztály tartalmazhat, a névtelen típus jó megoldás. A névtelen típusok akkor is kényelmesek, ha az egyes deklarációkhoz eltérő tulajdonságokat szeretne kiválasztani, vagy ha módosítani szeretné a tulajdonságok sorrendjét. Ha azonban a projekt több olyan objektumot is tartalmaz, amelyek azonos tulajdonságokkal rendelkeznek, rögzített sorrendben, akkor egyszerűbben deklarálhatja őket egy osztálykonstruktor nevesített típusával. Egy megfelelő konstruktor esetében például egyszerűbb egy osztály több példányának Product deklarálása, mint több névtelen típusú példány deklarálása.

' Declaring instances of a named type.
Dim firstProd1 As New Product("paperclips", 1.29)
Dim secondProd1 As New Product("desklamp", 28.99)
Dim thirdProd1 As New Product("stapler", 5.09)

' Declaring instances of an anonymous type.
Dim firstProd2 = New With {Key .Name = "paperclips", Key .Price = 1.29}
Dim secondProd2 = New With {Key .Name = "desklamp", Key .Price = 28.99}
Dim thirdProd2 = New With {Key .Name = "stapler", Key .Price = 5.09}

A névvel ellátott típusok másik előnye, hogy a fordító képes észlelni egy tulajdonságnév véletlen félreírását. Az előző példákbanfirstProd2secondProd2thirdProd2, és azonos névtelen típusú példányokként szolgálnak. Ha azonban véletlenül deklarálná thirdProd2 az alábbi módok egyikét, annak típusa eltérne az és firstProd2secondProd2a .

' Dim thirdProd2 = New With {Key .Name = "stapler", Key .Price = 5.09}
' Dim thirdProd2 = New With {Key .Name = "stapler", Key .Price = "5.09"}
' Dim thirdProd2 = New With {Key .Name = "stapler", .Price = 5.09}

Ennél is fontosabb, hogy vannak olyan korlátozások a névtelen típusok használatára vonatkozóan, amelyek nem vonatkoznak a névvel ellátott típusok példányaira. firstProd2, secondProd2és thirdProd2 azonos névtelen típusú példányok. A megosztott névtelen típus neve azonban nem érhető el, és nem jelenik meg ott, ahol típusnév várható a kódban. Egy névtelen típus például nem használható metódusadák definiálására, másik változó vagy mező deklarálására, vagy bármilyen típusdeklarációban. Ennek eredményeképpen a névtelen típusok nem megfelelőek, ha adatokat kell megosztania a módszerek között.

Névtelen típusdefiníció

Egy névtelen típusú példány deklarációjára válaszul a fordító létrehoz egy új osztálydefiníciót, amely tartalmazza a megadott tulajdonságokat.

Ha a névtelen típus legalább egy kulcstulajdonságot tartalmaz, a definíció felülbírálja a következőtől Objectörökölt három tagot: Equals, GetHashCodeés ToString. Az egyenlőség teszteléséhez és a kivonatkód értékének meghatározásához létrehozott kód csak a kulcstulajdonságokat veszi figyelembe. Ha a névtelen típus nem tartalmaz kulcstulajdonságokat, csak ToString felül lesz bírálva. A névtelen típusú explicit névvel ellátott tulajdonságok nem ütköznek ezekkel a létrehozott metódusokkal. Vagyis nem használhat .Equals, .GetHashCodeés .ToString nem nevezhet el tulajdonságot.

A névtelen típusdefiníciók, amelyek legalább egy kulcstulajdonságsal rendelkeznek, szintén implementálják az System.IEquatable<T> interfészt, ahol T a névtelen típus típusa.

A fordító által létrehozott kódról és a felülírt metódusok működéséről további információt a Névtelen típusdefiníció című témakörben talál.

Lásd még