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-onlypole 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že cust.Name je to řetězec.

    Dim custs1 = From cust In customers
                 Select cust.Name
    
  • custs2 obsahuje kolekci Customer objektů, protože každý prvek customers je Customer 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 Selectcust.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 , firstProd2a secondProd2thirdProd2 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, secondProd2a 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, .GetHashCodeani .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.

Viz také