Anonymní typy (Visual Basic)
Visual Basic podporuje anonymní typy, které umožňují vytvářet objekty bez zápisu definice třídy pro datový typ. Místo toho kompilátor vygeneruje třídu za vás. Třída nemá použitelný název, dědí přímo z Objecta obsahuje vlastnosti, které zadáte při deklarování objektu. Protože název datového typu není zadaný, označuje se jako anonymní typ.
Následující příklad deklaruje a vytvoří proměnnou product
jako instanci anonymního typu, který má dvě vlastnosti, Name
a Price
.
' Variable product is an instance of a simple anonymous type.
Dim product = New With {Key .Name = "paperclips", .Price = 1.29}
Výraz dotazu používá anonymní typy ke kombinování sloupců dat vybraných dotazem. Typ výsledku nelze předem definovat, protože nemůžete předpovědět sloupce, které může konkrétní dotaz vybrat. Anonymní typy umožňují napsat dotaz, který vybere libovolný počet sloupců v libovolném pořadí. Kompilátor vytvoří datový typ, který odpovídá zadaným vlastnostem a zadanému pořadí.
V následujícíchpříkladch products
Proměnná namePriceQuery
obsahuje definici dotazu, který při spuštění vrátí kolekci instancí anonymního typu, která má dvě vlastnosti Name
a Price
.
Dim namePriceQuery = From prod In products
Select prod.Name, prod.Price
Proměnná nameQuantityQuery
obsahuje definici dotazu, který při spuštění vrátí kolekci instancí anonymního typu, která má dvě vlastnosti Name
a OnHand
.
Dim nameQuantityQuery = From prod In products
Select prod.Name, prod.OnHand
Další informace o kódu vytvořeném kompilátorem pro anonymní typ naleznete v tématu Definice anonymního typu.
Upozornění
Název anonymního typu je generován kompilátorem a může se lišit od kompilace po kompilaci. Váš kód by neměl používat nebo spoléhat na název anonymního typu, protože se název může při opětovném zkompilování projektu změnit.
Deklarace anonymního typu
Deklarace instance anonymního typu používá seznam inicializátoru k určení vlastností typu. Vlastnosti lze zadat pouze v případě, že deklarujete anonymní typ, nikoli jiné prvky třídy, jako jsou metody nebo události. V následujícím příkladu je instance anonymního typu, product1
která má dvě vlastnosti: Name
a 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}
Pokud označíte vlastnosti jako vlastnosti klíče, můžete je použít k porovnání dvou instancí anonymního typu pro rovnost. Hodnoty vlastností klíče však nelze změnit. Další informace najdete v části Vlastnosti klíče dále v tomto tématu.
Všimněte si, že deklarace instance anonymního typu se podobá deklarování instance pojmenovaného typu pomocí inicializátoru objektů:
' Variable product3 is an instance of a class named Product.
Dim product3 = New Product With {.Name = "paperclips", .Price = 1.29}
Další informace o dalších způsobech určení vlastností anonymního typu naleznete v tématu Postupy: Odvození názvů a typů vlastností v deklaracích anonymního typu.
Hlavní vlastnosti
Klíčové vlastnosti se liší od vlastností, které nejsou klíči, několika základními způsoby:
Pouze hodnoty vlastností klíče se porovnávají, aby bylo možné určit, zda jsou dvě instance stejné.
Hodnoty vlastností klíče jsou jen pro čtení a nelze je změnit.
Do algoritmu hash generovaného kompilátorem pro anonymní typ jsou zahrnuty pouze hodnoty vlastností klíče.
Rovnost
Instance anonymních typů mohou být stejné pouze v případě, že jsou instancemi stejného anonymního typu. Kompilátor považuje dvě instance za instance stejného typu, pokud splňují následující podmínky:
Deklarují se ve stejném sestavení.
Jejich vlastnosti mají stejné názvy, stejné odvozené typy a jsou deklarovány ve stejném pořadí. Porovnání názvů nerozlišují malá a velká písmena.
Stejné vlastnosti jsou v každém označeny jako klíčové vlastnosti.
Nejméně jedna vlastnost v každé deklaraci je klíčovou vlastností.
Instance anonymníchtypůch
' 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))
Dvě instance stejného anonymního typu jsou stejné, pokud jsou hodnoty jejich vlastností klíče stejné. Následující příklady ukazují, jak se testuje rovnost.
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))
Hodnoty jen pro čtení
Hodnoty vlastností klíče nelze změnit. Například v prod8
předchozím příkladu Name
jsou read-only
pole a Price
pole , ale OnHand
lze je změnit.
' 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
Anonymní typy z výrazů dotazů
Výrazy dotazů nevyžadují vždy vytváření anonymních typů. Pokud je to možné, k uložení dat ve sloupci používají existující typ. K tomu dochází, když dotaz vrátí buď celé záznamy ze zdroje dat, nebo pouze jedno pole z každého záznamu. V následujících příkladech customers
kódu je kolekce objektů Customer
třídy. Třída má mnoho vlastností a v libovolném pořadí můžete do výsledku dotazu zahrnout jeden nebo více z nich. V prvních dvou příkladech nejsou vyžadovány žádné anonymní typy, protože dotazy vybírají prvky pojmenovaných typů:
custs1
obsahuje kolekci řetězců, protožecust.Name
je to řetězec.Dim custs1 = From cust In customers Select cust.Name
custs2
obsahuje kolekciCustomer
objektů, protože každý prvekcustomers
jeCustomer
objekt a celý prvek je vybrán dotazem.Dim custs2 = From cust In customers Select cust
Vhodné pojmenované typy však nejsou vždy k dispozici. Můžete chtít vybrat jména a adresy zákazníků pro jeden účel, čísla ID zákazníka a umístění pro jiné a jména zákazníků, adresy a historii objednávek pro třetí. Anonymní typy umožňují vybrat libovolnou kombinaci vlastností v libovolném pořadí, aniž byste nejprve deklarovali nový pojmenovaný typ, který bude obsahovat výsledek. Místo toho kompilátor vytvoří anonymní typ pro každou kompilaci vlastností. Následující dotaz vybere pouze jméno a ID zákazníka z každého Customer
objektu v objektu customers
. Kompilátor proto vytvoří anonymní typ, který obsahuje pouze tyto dvě vlastnosti.
Dim custs3 = From cust In customers
Select cust.Name, cust.ID
Názvy i datové typy vlastností v anonymním typu jsou převzaty z argumentů do Select
cust.Name
a cust.ID
. Vlastnosti v anonymním typu vytvořeném dotazem jsou vždy klíčové vlastnosti. Při custs3
spuštění v následující For Each
smyčce je výsledkem kolekce instancí anonymního typu se dvěma vlastnostmi Name
klíče a ID
.
For Each selectedCust In custs3
Console.WriteLine(selectedCust.ID & ": " & selectedCust.Name)
Next
Prvky v kolekci reprezentované silným typem custs3
jsou silného typu a pomocí technologie IntelliSense můžete procházet dostupné vlastnosti a ověřit jejich typy.
Další informace naleznete v tématu Úvod do LINQ v jazyce Visual Basic.
Rozhodování o použití anonymních typů
Před vytvořením objektu jako instance anonymní třídy zvažte, zda je to nejlepší možnost. Pokud například chcete vytvořit dočasný objekt, který bude obsahovat související data, a nepotřebujete žádná další pole a metody, které by mohla úplná třída obsahovat, je anonymní typ dobrým řešením. Anonymní typy jsou také vhodné, pokud chcete pro každou deklaraci použít jiný výběr vlastností nebo pokud chcete změnit pořadí vlastností. Pokud však projekt obsahuje několik objektů se stejnými vlastnostmi, můžete je deklarovat snadněji pomocí pojmenovaného typu s konstruktorem třídy. Například s odpovídajícím konstruktorem je jednodušší deklarovat několik instancí Product
třídy, než je deklarovat několik instancí anonymního typu.
' 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}
Další výhodou pojmenovaných typů je, že kompilátor dokáže zachytit náhodné chybné zatypování názvu vlastnosti. V předchozích příkladech , firstProd2
a secondProd2
thirdProd2
jsou určeny pro instance stejného anonymního typu. Pokud byste však omylem deklarovali thirdProd2
jedním z následujících způsobů, jeho typ by se liší od typu firstProd2
a secondProd2
.
' 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}
Důležitější je, že existují omezení použití anonymních typů, které se nevztahují na instance pojmenovaných typů. firstProd2
, secondProd2
a thirdProd2
jsou instance stejného anonymního typu. Název sdíleného anonymního typu však není k dispozici a nemůže se zobrazit, kde se v kódu očekává název typu. Anonymní typ například nelze použít k definování podpisu metody, k deklaraci jiné proměnné nebo pole nebo v jakékoli deklaraci typu. V důsledku toho nejsou anonymní typy vhodné, pokud potřebujete sdílet informace mezi metodami.
Definice anonymního typu
V reakci na deklaraci instance anonymního typu kompilátor vytvoří novou definici třídy, která obsahuje zadané vlastnosti.
Pokud anonymní typ obsahuje alespoň jednu vlastnost klíče, definice přepíše tři členy zděděné z Object: Equals, GetHashCodea ToString. Kód vytvořený pro testování rovnosti a určení hodnoty kódu hash považuje pouze vlastnosti klíče. Pokud anonymní typ neobsahuje žádné vlastnosti klíče, přepíše se pouze ToString . Explicitně pojmenované vlastnosti anonymního typu nemohou být v konfliktu s těmito vygenerovanými metodami. To znamená, že nelze použít .Equals
, .GetHashCode
ani .ToString
pojmenovat vlastnost.
Definice anonymního typu, které mají alespoň jednu vlastnost klíče, také implementují System.IEquatable<T> rozhraní, kde T
je typ anonymního typu.
Další informace o kódu vytvořeném kompilátorem a funkcí přepsaných metod naleznete v tématu Definice anonymního typu.