Делать автобокс и распаковку ведут себя по-разному в Java и C#
Я вручную конвертирую код из 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
Я был бы признателен за систематический анализ различий и любого обоснования.
2 ответа
В вашем примере на C# не происходит ни бокс, ни распаковка (и автобокс). double
это просто псевдоним для struct
Double
,
На Java бокс нужен. Из-за стирания типа вы не можете создать List<double>
, только List<Double>
, Во время компиляции, List<?>
становится List<Object>
и бокс / распаковка должны произойти, чтобы вы могли добавить переменную собственного типа в List<Object>
или присвойте собственную переменную элементу списка.
В C# double
а также Double
это одно и то же (если вы не создали свой собственный тип с именем Double
что было бы глупо).
double
определяется как псевдоним global::System.Double
, Таким образом, здесь нет бокса.
В яве, Double
в штучной упаковке double
с удалением типа является ключевой частью реализации обобщений.