Klasa anonimowa jest najczęściej używana przy wartościach zwracanych przez LINQ. Jest ona dostępna tylko w bloku kodu, w którym została utworzona.
Może ona posiadać tylko pola publiczne, które wszystkie muszą zostać zainicjalizowane. Nie może ona zawierać metod oraz pól statycznych.

Aby stworzyć zmienną referencyjną do obiektu klasy anonimowej należy użyć słowa kluczowego var, ponieważ nasz obiekt klasy anonimowej nie ma typu.
Następnie używasz słowa kluczowego new oraz dwa nawiasy klamrowe, można w nich przypisać dowolne pola oraz ich wartości.

Przykład:

   class Program{
        static void Main(){

            var student = new {Imie="Adam", Nazwisko="Adamski", Wiek=23 };

        }
}

Podczas tworzenia obiektu anonimowej klasy w nawiasach klamrowych nie podajemy typu pola.
Gdy spróbujemy kompilator zgłosi błąd. Zobaczmy przykład:

   class Program{
        static void Main(){

            var student = new { string Imie="Adam", Nazwisko="Adamski", Wiek=23 };

        }

anon1
Rys. Błąd zgłoszony przez kompilator

Do pól w obiekcie klasy anonimowej odnosimy się w standardowy sposób za pomocą kropki.
Zobaczmy przykład:

    class Program{
        static void Main(){

            var student = new { Imie="Adam", Nazwisko="Adamski", Wiek=23 };

            Console.WriteLine("Imie {0}, Nazwisko {1}, Wiek {2}", student.Imie, student.Nazwisko, student.Wiek);
            Console.ReadLine();

        }
}

anon2

Rys. Rezultat działania aplikacji

Wszystkie pola obiektu klasy anonimowej są tylko do odczytu. Zobaczmy przykład:

   class Program{
        static void Main(){

            var student = new { Imie="Adam", Nazwisko="Adamski", Wiek=23 };

            student.Wiek = 40;           

        }
}

anon3

Rys. Błąd zgłoszony przez kompilator.

W przykładach powyżej stworzyliśmy zmienną referencyjna wskazującą na obiekt klasy anonimowej. Zmienną tą nazwaliśmy student.
Spróbujmy stworzyć nowy obiekt klasy anonimowej przypiszmy go do zmiennej o nazwie student2. W której pola będą posiadać identyczne nazwy i kolejność lecz inne wartości. Następnie spróbujmy przypisać referencje z student2 do student.

 class Program{
        static void Main(){

            var student = new { Imie="Adam", Nazwisko="Adamski", Wiek=23 };
            var student2 = new { Imie = "Kamil", Nazwisko = "Kozak", Wiek = 21 };
            student = student2;

            Console.WriteLine("Imie {0}, Nazwisko {1}, Wiek {2}", student.Imie, student.Nazwisko, student.Wiek);
       

            Console.ReadLine();

        }

anon4

Rys. Rezultat działania aplikacji

Jak widzimy udało nam się. Jednak gdy zmienimy kolejność pól w klasie anonimowej. Kompilator będzie rozpoznawał tą klasę po zmianach jako całkiem inna i operacja przypisania referencji nie będzie możliwa. Zobaczmy przykład:

   class Program{
        static void Main(){

            var student = new { Imie="Adam", Nazwisko="Adamski", Wiek=23 };
            var student2 = new { Nazwisko = "Kozak",Imie = "Kamil" , Wiek = 21 };
            student = student2;        

        }
}

anon5

Rys. Błąd zgłoszony przez kompilator.

Sprawdźmy zachowanie metody Equals() podczas porównania dwóch klas anonimowych o takich samych polach i ich wartościach.
Przykład:

   class Program{
        static void Main(){

            var student = new { Imie="Adam", Nazwisko="Adamski", Wiek=23 };
            var student2 = new { Imie = "Adam", Nazwisko = "Adamski", Wiek = 23 };
           
            if (student.Equals(student2))
            {
                Console.WriteLine("Obiekty są takie same");
            }
            else {
                Console.WriteLine("Obiekty nie są takie same");
            }

            Console.ReadLine();
        }
}

anon6

Rys. Rezultat działania aplikacji

Jak widzimy metoda Equals zadziałała poprawnie. Dzieje się tak ponieważ kompilator posiada przeciążoną wersję tej metody dla typów anonimowych.
Sprawdźmy jak zachowa się operator ==.
Przykład:

  class Program{
        static void Main(){

            var student = new { Imie="Adam", Nazwisko="Adamski", Wiek=23 };
            var student2 = new { Imie = "Adam", Nazwisko = "Adamski", Wiek = 23 };
           
            if (student== student2)
            {
                Console.WriteLine("Obiekty są takie same");
            }
            else {
                Console.WriteLine("Obiekty nie są takie same");
            }

            Console.ReadLine();
        }
}

anon7

Rys. Rezultat działania aplikacji

Jak widzimy operator == zwrócił wartość false i otrzymaliśmy komunikat “Obiekty nie są takie same”. Dzieje się tak ponieważ ten operator nie został  przeciążony i porównywane są referencje do obiektów a nie wartości pól. Co jest standardowym zachowaniem operatora == w przypadku klas.

Podsumowanie:
Klasa anonimowa posiada pewne ograniczenia:
– Dostępna jest tylko w bloku kodu, w którym została utworzona.
– Może posiadać tylko pola publiczne.
– Wszystkie pola muszą zostać zainicjalizowane.
– Nie może zawierać metod oraz pól statycznych.
– Pola są tylko do odczytu
Gdy chcemy porównać dwa obiekty klasy anonimowej możemy skorzystać z metody Equals. Operator == porówna nam referencje do obiektów.