Anonymní typy (Průvodce programováním v C#)

Anonymní typy poskytují pohodlný způsob zapouzdření sady vlastností jen pro čtení do jednoho objektu bez definování pojmenovaného typu jako první. Kompilátor vygeneruje název typu v době kompilace, ke kterému nemáte přístup ve zdrojovém kódu. Kompilátor odvodí typ každé vlastnosti.

Vytvořte anonymní typy pomocí operátoru new společně s inicializátorem objektů. Následující příklad ukazuje anonymní typ inicializovaný se dvěma vlastnostmi Name a Age:

var person = new { Name = "Alice", Age = 30 };
Console.WriteLine($"{person.Name} is {person.Age} years old.");
// Output:
// Alice is 30 years old.

Odvozené názvy vlastností

Názvy vlastností můžete explicitně zadat pomocí Name = value syntaxe. Při inicializaci anonymního typu pomocí proměnné nebo výrazu přístupu člena kompilátor odvodí název vlastnosti z daného výrazu:

string productName = "Laptop";
decimal price = 999.99m;
var product = new { productName, price };
Console.WriteLine($"{product.productName}: {product.price:C}");
// Output:
// Laptop: $999.99

V předchozím příkladu kompilátor odvodí productName a price jako názvy vlastností z názvů proměnných použitých v inicializátoru.

Deklarace anonymních typů pomocí var

Vzhledem k tomu, že kompilátor vygeneruje název typu a nemůžete k němu přistupovat ve zdrojovém kódu, musíte použít var k deklaraci místní proměnné. Název typu není možné explicitně zadat:

// You must use var — you can't write a named type here.
var person = new { Name = "Alice", Age = 30 };

Použití anonymních typů v dotazech LINQ

Anonymní typy se nejčastěji zobrazují v select klauzuli výrazu dotazu, kde projektují podmnožinu vlastností z každého zdrojového prvku:

var words = new[] { "apple", "blueberry", "cherry" };

var results = words.Select(w => new { Word = w, Length = w.Length });

foreach (var item in results)
{
    Console.WriteLine($"{item.Word} has {item.Length} letters.");
}
// Output:
// apple has 5 letters.
// blueberry has 9 letters.
// cherry has 6 letters.

Rovnost

Dvě instance anonymního typu, které mají stejné názvy vlastností a typy ve stejném pořadí, sdílejí stejný typ vygenerovaný kompilátorem. Kompilátor přepisuje Equals a GetHashCode aby rovnost porovnávala hodnoty vlastností místo odkazování na identitu:

var a = new { Name = "Alice", Age = 30 };
var b = new { Name = "Alice", Age = 30 };
var c = new { Name = "Bob", Age = 25 };

Console.WriteLine(a.Equals(b));  // True
Console.WriteLine(a.Equals(c));  // False

Vnořené anonymní typy

Anonymní typy můžou obsahovat jiné anonymní typy jako hodnoty vlastností:

var order = new
{
    OrderId = 1,
    Customer = new { Name = "Alice", City = "Seattle" },
    Total = 150.00m
};
Console.WriteLine($"Order {order.OrderId} for {order.Customer.Name} in {order.Customer.City}");
// Output:
// Order 1 for Alice in Seattle

Charakteristiky

Anonymní typy mají následující charakteristiky:

  • Kompilátor je generuje jako internal sealed class typy, které jsou odvozeny z Object.
  • Všechny vlastnosti jsou public a jen pro čtení.
  • Anonymní typy podporují with výrazy pro nedestruktivní mutaci.
  • Kompilátor generuje přepisy založené na hodnotách pro Equals, GetHashCode a ToString.
  • Anonymní typy podporují stromy výrazů, zatímco n-tice ne.

Omezení

Anonymní typy mají několik omezení:

  • Nemůžete je použít jako návratové typy metod, parametry metody nebo typy polí, protože typ nemůžete pojmenovat.
  • Jejich rozsah je omezen na metodu, ve které je deklarujete.
  • Nemůžete přidávat metody, události ani vlastní operátory.
  • Vlastnosti jsou vždy jen pro čtení; anonymní typy nepodporují proměnlivé vlastnosti.

Kdy místo toho použít řazené kolekce členů

U většiny nových kódů zvažte použití řazených kolekcí členů místo anonymních typů. Jako typy hodnot poskytují n-tice lepší výkon. Poskytují také podporu dekonstrukce a flexibilnější syntaxi. Anonymní typy zůstávají lepší volbou, pokud potřebujete podporu stromu výrazů nebo sémantiku typu odkaz. Podrobné porovnání naleznete v tématu Volba mezi anonymními a n-ticovými typy.

Viz také