Автоупаковка и распаковка ведут себя по-разному в Java и C#
-
22-09-2019 - |
Вопрос
Я вручную конвертирую код из Java (1.6) в C# и обнаружил некоторые трудности с поведением примитивов (int и double).В C# кажется, что почти все преобразования происходят автоматически.
List<double> list1 = new List<double>(); // legal, C#
double d0 = 3.0;
list1.Add(d0); // legal, C#
Double dd = 2.3f; // legal, C#
list1.Add(dd); // legal, C#
List<Double> list2 = new List<Double>(); // legal, C#
double d1 = 3.0;
list2.Add(d1); // legal, C#
list2.Add(2.0); // legal, C#
double d2 = list2.get(0); // legal, C#
но в Java разрешены только некоторые
List<double> list1 = new ArrayList<double>(); // illegal, Java
List<Double> list2 = new ArrayList<Double>(); // legal, Java
double d1 = 3.0;
list2.add(d1); // legal, Java
list2.add(2.0); // legal, Java
double d2 = list2.get(0); // legal, Java
Я был бы признателен за систематический анализ различий и любое их обоснование.
Решение
В вашем примере на С# не происходит упаковки или распаковки (и автобокса). double
это просто псевдоним для struct
Double
.
В Java бокс необходим.Из-за стирание типа, вы не можете создать List<double>
, только List<Double>
.Во время компиляции List<?>
становится List<Object>
и необходимо будет выполнить упаковку/распаковку, чтобы вы могли добавить переменную собственного типа в List<Object>
или назначьте собственную переменную элементу списка.
Другие советы
В С#, double
и Double
являются точно то же самое (пока вы не создали свой собственный тип под названием Double
, что было бы глупо).
double
является определенный как псевдоним global::System.Double
.Как такового бокса здесь нет.
В Яве, Double
это коробочная версия double
, причем стирание типов является ключевой частью реализации дженериков.