MySQL Java JavaScript PHP Python HTML-CSS C-sharp

Tipuri anonime

Tipurile anonime permit crearea unui obiect cu un anumit set de proprietăți fără a defini o clasă. Un tip anonim este definit cu ajutorul cuvântului cheie var și al inițializatorului de obiecte:

var user = new { Name = "Tom", Age = 34 };
Console.WriteLine(user.Name);

În acest caz, user este un obiect de tip anonim, care are definite două proprietăți Name și Age. Putem folosi proprietățile acestuia la fel ca și în cazul obiectelor claselor obișnuite. Totuși, există o limitare - proprietățile tipurilor anonime sunt disponibile doar pentru citire.

În timpul compilării, compilatorul va crea automat un nume de tip pentru el și va folosi acest nume la accesarea obiectului. Adesea, tipurile anonime au un nume de genul <>f__AnonymousType0'2.

Pentru mediul de execuție CLR, tipurile anonime vor reprezenta, la fel ca și clasele, un tip referențial.

Dacă în program sunt folosite mai multe obiecte de tip anonim cu același set de proprietăți, compilatorul va crea o singură definiție a tipului anonim:

var user = new { Name = "Tom", Age = 34 };
var student = new { Name = "Alice", Age = 21 };
var manager = new { Name = "Bob", Age = 26, Company = "Microsoft" };

Console.WriteLine(user.GetType().Name); // <>f__AnonymousType0'2
Console.WriteLine(student.GetType().Name); // <>f__AnonymousType0'2
Console.WriteLine(manager.GetType().Name); // <>f__AnonymousType1'3

Aici, user și student vor avea aceeași definiție a tipului anonim. Cu toate acestea, astfel de obiecte nu pot fi convertite la alt tip, de exemplu, la o clasă, chiar dacă aceasta are un set similar de proprietăți.

Trebuie luat în considerare faptul că proprietățile unui obiect anonim pot fi setate doar în inițializator. În afara inițializatorului nu le putem atribui valori. Astfel, de exemplu, în următorul caz vom întâmpina o eroare:

var student = new { Name = "Alice", Age = 21 };
student.Age = 32;   // ! Eroare

Pe lângă forma de inițializare folosită mai sus, când atribuim proprietăților anumite valori, putem folosi și inițializatori cu proiecție, unde putem transmite în inițializator anumiți identificatori ale căror nume vor fi folosite ca denumiri ale proprietăților:

Person tom = new Person("Tom");
int age = 34;
var student = new { tom.Name, age }; // inițializator cu proiecție
Console.WriteLine(student.Name);
Console.WriteLine(student.age);

class Person
{
   public string Name { get; set; }
   public Person(string name) => Name = name;
}

În acest caz, definirea obiectului anonim va fi de fapt identică cu următoarea:

var student = new { Name = tom.Name, age = age};

Denumirile proprietăților și variabilelor (Name și age) vor fi folosite ca denumiri ale proprietăților obiectului.

De asemenea, putem defini array-uri de obiecte de tip anonim:

var people = new[]
{
   new {Name="Tom"},
   new {Name="Bob"}
};
foreach(var p in people)
{
   Console.WriteLine(p.Name);
}

De ce sunt necesare tipurile anonime? Uneori apare necesitatea de a folosi un tip într-un context restrâns sau chiar o singură dată. Crearea unei clase pentru un astfel de tip poate fi redundantă.

Dacă dorim să adăugăm o proprietate, o putem face direct la locul obiectului anonim. În cazul unei clase, ar trebui să modificăm și clasa, care poate să nu mai fie folosită în altă parte.

O situație tipică este obținerea rezultatului unei selecții dintr-o bază de date: obiectele sunt folosite doar pentru a obține selecția și adesea nu mai sunt folosite în altă parte, iar crearea unor clase pentru ele ar fi excesivă. Un obiect anonim este ideal pentru stocarea temporară a selecției.

← Lecția anterioară Lecția următoare →