Jasica.Net

C#, .Net, SQL i nie tylko

Dostęp do właściwości obiektów anonimowych bez refleksji

W tym wpisie pragnę zaprezentować kolejną ciekawą właściwość języka C#- tym razem odnosić się będzie ona do anonimowych obiektów.


Spójrzmy, więc na poniższy kod:


        static object GetAnonymousObject()
        {
            return new { Foo = 1, Bar = 2 };
        }

        static void Main(string[] args)
        {
            var obj = GetAnonymousObject();
            var something = ...;

            Console.WriteLine("Foo={0}, Bar={1}", something.Foo, something.Bar);
        }

Co należyt wstawić w miejsce kropek, aby kod kompilował się, a także nie powodował błędów w czasie wykonywania? Przykładowe rozwiązanie prezentuje poniżej.


        static void Main(string[] args)
        {
            var obj = GetAnonymousObject();
            var something = Cast(obj, new { Foo = 0, Bar = 0, Z = 0});

            Console.WriteLine("Foo={0}, Bar={1}", something.Foo, something.Bar);
        }

        static T Cast<T>(object obj, T tmpInstance)
        {
            return (T) obj;
        }


Analizując powyższy kod można zacząć się zastanawiać co pozwala mu działać nie powodując wyjątków rzutowania. Stoi za tym optymalizacja kompilatora, która dba o to by nie generować zbędnych typów anonimowych zawierających takie same zestawy właściwości. Warto, więc zauważyć, że dodanie lub usunięcie jakiegokolwiek pola z typu spowoduje rzucenie wyjątku nieprawidłowego rzutowania.

 

Jak wspomniałem na początku, jest to ciekawostka i należy podchodzić do niej ostrożnie. Zazwyczaj użycie standardowych mechanizmów refleksji czy obiektów dynamicznych lepszym rozwiązaniem.