Dziwna sprawa rzutowania typów

Dziwna sprawa rzutowania typów
AN
  • Rejestracja:około 19 lat
  • Ostatnio:około 21 godzin
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#.

Kopiuj
            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;
Kopiuj
            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".

edytowany 1x, ostatnio: andrzejlisek
somekind
Moderator
  • Rejestracja:około 17 lat
  • Ostatnio:około 11 godzin
  • Lokalizacja:Wrocław
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;.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.