Anonymní typy
Anonymní typy poskytují pohodlný způsob zapouzdření sady vlastností jen pro čtení do jednoho objektu, aniž byste museli explicitně definovat typ jako první. Název typu je generován kompilátorem a není k dispozici na úrovni zdrojového kódu. Typ každé vlastnosti je odvozen kompilátorem.
Anonymní typy vytvoříte pomocí operátoru new
společně s inicializátorem objektů. Další informace o inicializátorech objektů naleznete v tématu Inicializátory objektů a kolekcí.
Následující příklad ukazuje anonymní typ, který je inicializován se dvěma vlastnostmi pojmenovanými Amount
a Message
.
var v = new { Amount = 108, Message = "Hello" };
// Rest the mouse pointer over v.Amount and v.Message in the following
// statement to verify that their inferred types are int and string.
Console.WriteLine(v.Amount + v.Message);
Anonymní typy se obvykle používají v select
klauzuli výrazu dotazu k vrácení podmnožinu vlastností z každého objektu ve zdrojové sekvenci. Další informace odotazch
Anonymní typy obsahují jednu nebo více veřejných vlastností jen pro čtení. Nejsou platné žádné jiné druhy členů třídy, jako jsou metody nebo události. Výraz použitý k inicializaci vlastnosti nemůže být null
, anonymní funkce nebo typ ukazatele.
Nejběžnějším scénářem je inicializace anonymního typu s vlastnostmi z jiného typu. V následujícím příkladu předpokládejme, že třída existuje s názvem Product
. Třída Product
obsahuje Color
a Price
vlastnosti společně s dalšími vlastnostmi, které vás nezajímají. Proměnná products
je kolekce Product
objektů. Deklarace anonymního typu začíná klíčovým slovem new
. Deklarace inicializuje nový typ, který používá pouze dvě vlastnosti z Product
. Použití anonymních typů způsobí vrácení menšího množství dat v dotazu.
Pokud nezadáte názvy členů v anonymním typu, kompilátor dává členům anonymního typu stejný název jako vlastnost, která se používá k jejich inicializaci. Zadáte název vlastnosti, která se inicializuje pomocí výrazu, jak je znázorněno v předchozím příkladu. V následujícím příkladu jsou názvy vlastností anonymního typu Color
a Price
.
var productQuery =
from prod in products
select new { prod.Color, prod.Price };
foreach (var v in productQuery)
{
Console.WriteLine("Color={0}, Price={1}", v.Color, v.Price);
}
Tip
Pravidlo stylu .NET můžete použít IDE0037 k vynucení, jestli jsou upřednostňované odvozené nebo explicitní názvy členů.
Je také možné definovat pole podle objektu jiného typu: třída, struktura nebo dokonce jiný anonymní typ. Provádí se pomocí proměnné držící tento objekt stejně jako v následujícím příkladu, kde jsou vytvořeny dva anonymní typy pomocí již vytvořených uživatelem definovaných typů. V obou případech bude product
pole v anonymním Product
typu shipment
a shipmentWithBonus
bude obsahovat výchozí hodnoty každého pole. bonus
Pole bude anonymního typu vytvořeného kompilátorem.
var product = new Product();
var bonus = new { note = "You won!" };
var shipment = new { address = "Nowhere St.", product };
var shipmentWithBonus = new { address = "Somewhere St.", product, bonus };
Při inicializaci proměnné pomocí anonymního typu obvykle deklarujete proměnnou jako implicitně zatypovanou místní proměnnou pomocí proměnné var. Název typu nelze zadat v deklaraci proměnné, protože k základnímu názvu anonymního typu má přístup pouze kompilátor. Další informaceochch var
Pole anonymně zadaných elementů můžete vytvořit kombinací implicitně zadané místní proměnné a implicitně zadaného pole, jak je znázorněno v následujícím příkladu.
var anonArray = new[] { new { name = "apple", diam = 4 }, new { name = "grape", diam = 1 }};
Anonymní typy jsou class
typy, které jsou odvozeny přímo z object
, a které nelze přetypovat na žádný typ s výjimkou object
. Kompilátor poskytuje název pro každý anonymní typ, i když k němu aplikace nemá přístup. Z pohledu modulu CLR (Common Language Runtime) se anonymní typ neliší od jiného typu odkazu.
Pokud dva nebo více anonymních inicializátorů objektů v sestavení určují posloupnost vlastností, které jsou ve stejném pořadí a mají stejné názvy a typy, kompilátor zachází s objekty jako s instancemi stejného typu. Sdílejí stejné informace o typu generovaném kompilátorem.
Anonymní typy podporují nedestruktivní mutování ve formě výrazů. To umožňuje vytvořit novou instanci anonymního typu, kde jedna nebo více vlastností má nové hodnoty:
var apple = new { Item = "apples", Price = 1.35 };
var onSale = apple with { Price = 0.79 };
Console.WriteLine(apple);
Console.WriteLine(onSale);
Nelze deklarovat pole, vlastnost, událost nebo návratový typ metody jako anonymní typ. Podobně nelze deklarovat formální parametr metody, vlastnosti, konstruktoru nebo indexeru jako anonymní typ. Chcete-li předat anonymní typ nebo kolekci, která obsahuje anonymní typy, jako argument metody, můžete deklarovat parametr jako typ object
. Použití object
pro anonymní typy však porazí účel silného psaní. Pokud je nutné uložit výsledky dotazu nebo je předat mimo hranice metody, zvažte použití obyčejné pojmenované struktury nebo třídy namísto anonymního typu.
Vzhledem k tomu, že Equals anonymní typy a GetHashCode metody jsou definovány z hlediska Equals
a GetHashCode
metod vlastností, jsou dvě instance stejného anonymního typu stejné, pouze pokud jsou všechny jejich vlastnosti stejné.
Poznámka:
Úroveň přístupnosti anonymního typu je internal
, proto dva anonymní typy definované v různých sestaveních nejsou stejného typu.
Proto instance anonymních typů nemohou být navzájem rovny, pokud jsou definovány v různých sestaveních, i když mají všechny jejich vlastnosti stejné.
Anonymní typy přepíší metodu ToString , zřetězení názvu a ToString
výstupu každé vlastnosti obklopené složenými závorkami.
var v = new { Title = "Hello", Age = 24 };
Console.WriteLine(v.ToString()); // "{ Title = Hello, Age = 24 }"