Typy anonimowe (Przewodnik programowania w języku C#)

Typy anonimowe zapewniają wygodny sposób hermetyzacji zestawu właściwości tylko do odczytu w pojedynczy obiekt bez uprzedniego zdefiniowania nazwanego typu. Kompilator generuje nazwę typu w czasie kompilacji, do której nie można uzyskać dostępu w kodzie źródłowym. Kompilator wywnioskuje typ każdej właściwości.

Utwórz typy anonimowe przy użyciu new operatora razem z inicjatorem obiektów. W poniższym przykładzie pokazano typ anonimowy zainicjowany z dwiema właściwościami Name i Age:

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

Wywnioskowane nazwy właściwości

Nazwy właściwości można jawnie określić przy użyciu Name = value składni. Podczas inicjowania typu anonimowego za pomocą zmiennej lub wyrażenia dostępu do składowej kompilator wywnioskuje nazwę właściwości z tego wyrażenia:

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

W poprzednim przykładzie kompilator wnioskuje productName oraz price jako nazw właściwości na podstawie nazw zmiennych użytych w inicjatorze.

Deklarowanie typów anonimowych przy użyciu wartości var

Ponieważ kompilator generuje nazwę typu i nie można uzyskać do niej dostępu w kodzie źródłowym, należy użyć var polecenia w celu zadeklarowania zmiennej lokalnej. Nie można jawnie określić nazwy typu:

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

Używanie typów anonimowych w zapytaniach LINQ

Typy anonimowe są najczęściej wyświetlane w select klauzuli wyrażenia zapytania, gdzie projektują podzestaw właściwości z każdego elementu źródłowego:

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.

Równość

Dwa wystąpienia typu anonimowego, które mają te same nazwy właściwości i typy w tej samej kolejności, mają ten sam typ wygenerowany przez kompilator. Kompilator przesłania elementy Equals i GetHashCode w ten sposób, że porównanie równości dotyczy wartości właściwości, a nie tożsamości referencyjnej.

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

Zagnieżdżone typy anonimowe

Typy anonimowe mogą zawierać inne typy anonimowe jako wartości właściwości:

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

Charakterystyka

Typy anonimowe mają następujące cechy:

  • Kompilator generuje je jako internal sealed class typy wywodzące się z Object.
  • Wszystkie właściwości są public i tylko do odczytu.
  • Typy anonimowe obsługują with wyrażenia dla mutacji niestrukcyjnej.
  • Kompilator generuje przesłonięcia oparte na wartościach Equals, GetHashCode i ToString.
  • Typy anonimowe obsługują drzewa wyrażeń, a krotki nie.

Ograniczenia

Typy anonimowe mają kilka ograniczeń:

  • Nie można ich używać jako typów zwracanych metod, parametrów metody lub typów pól, ponieważ nie można nazwać typu.
  • Są one ograniczone do metody, w której je deklarujesz.
  • Nie można dodawać metod, zdarzeń ani operatorów niestandardowych.
  • Właściwości są zawsze tylko do odczytu; Typy anonimowe nie obsługują właściwości modyfikowalnych.

Kiedy zamiast tego należy używać krotki

W przypadku większości nowego kodu rozważ użycie krotek zamiast typów anonimowych. Jako typy wartości krotki zapewniają lepszą wydajność. Zapewniają one również obsługę dekonstrukcji i bardziej elastyczną składnię. Typy anonimowe pozostają lepszym wyborem, jeśli potrzebujesz obsługi drzewa wyrażeń lub semantyki typów referencyjnych. Aby uzyskać szczegółowe porównanie, zobacz Wybieranie między typami anonimowymi a krotkami.

Zobacz także