Dziwna sprawa rzutowania typów

0

W C# jest możliwe rzutowanie, czyli odczyt danego obiektu jako obiekt zadanego typu. Jest też typ "obiekt", który jest typem nieokreślonym i może zawierać w sobie obiekt dowolnego typu, tylko, że odczyt zawsze następuje z rzutowaniem, ale CLI zawsze wie, jakiego typu jest obiekt w danej chwili. Do rozważenia dwa kody w C#.

            double Dbl = 1.23;
            decimal Dec = 4.56M;

            object Ob1 = Dbl;
            object Ob2 = Dec;

            double X0 = (double)Ob1;
            int X = (int)X0;

            decimal Y0 = (decimal)Ob2;
            double Y = (double)Y0;
            double Dbl = 1.23;
            decimal Dec = 4.56M;

            object Ob1 = Dbl;
            object Ob2 = Dec;

            object X0 = (double)Ob1;
            int X = (int)X0;

            object Y0 = (decimal)Ob2;
            double Y = (double)Y0;

W mojej interpretacji oba kody to jest dokładnie to samo, bo w obu występuje próba odczytu obiektu typu "decimal" jako "double", oraz próba odczytu obiektu typu "double" jako "integer". Jedyna różnica jest taka, że przyjmując założenia, że "obiekt" może przechowywać dowolną wartość, mogę zamienić typy pośrednich zmiennych (X0 i Y0) które odczytuję wyłącznie z rzutowaniem na "obiekt" i też powinno być dobrze. Dlaczego pierwszy kod przebiega bez problemów, a w drugim jest błąd niemożności zmiany typu obiektu? W chwili próby dokonania zmiany typu w obu przypadkach X0 przechowuje wartość typu "double", a obiekt Y0 przechowuje wartość typu "decimal".

2

To nie jest to samo, bo to nie jest nawet rzutowanie. Zmiana typu wartościowego na referencyjny, czyli w tym przypadku decimal i double na object to opakowanie (boxing), w drugą stronę to rozpakowanie (unboxing). W drugim Twoim kodzie zmienna X0 to object opakowujący double, więc zanim go zrzutujesz na int, musisz go najpierw rozpakować do typu, który miała przed zapakowaniem, czyli: int X = (int)(double)X0;.

1 użytkowników online, w tym zalogowanych: 0, gości: 1