Бесполезные ожидания от компилятора при работе с дженериками?C#

Место общения программистов C#
Ответить Пред. темаСлед. тема
Anonymous
 Бесполезные ожидания от компилятора при работе с дженериками?

Сообщение Anonymous »

Компилятор, который должен транслировать общий тип или метод (на любой язык, а не только на Java), в принципе имеет два варианта:


Специализация кода. Компилятор генерирует новое представление для
каждого экземпляра универсального типа или метода. Например,
компилятор будет генерировать код для списка целых чисел и дополнительный
другой код для списка строк, списка дат, списка
буферов и так далее.

Совместное использование кода. Компилятор генерирует код только для одного представления
универсального типа или метода и сопоставляет все экземпляры
универсального типа или метода с уникальным представлением, выполняя
проверки типов и преобразования типов, где это необходимо. .


В Java используется метод совместного использования кода. Я считаю, что C# следует методу специализации кода, поэтому, по моему мнению, весь приведенный ниже код является логичным, используя C#.

Предполагая, что этот фрагмент кода Java:

Код: Выделить всё

public class Test {

public static void main(String[] args) {
Test t = new Test();
String[] newArray = t.toArray(new String[4]);
}

@SuppressWarnings("unchecked")
public  T[] toArray(T[] a) {
//5 as static size for the sample...
return (T[]) Arrays.copyOf(a, 5, a.getClass());
}
}
Метод совместного использования кода приведет к этому коду после удаления типа:

Код: Выделить всё

public class Test {

public static void main(String[] args) {
Test t = new Test();
//Notice the cast added by the compiler here
String[] newArray = (String[])t.toArray(new String[4]);
}

@SuppressWarnings("unchecked")
public Object[] toArray(Object[] a) {
//5 as static size for the sample...
return Arrays.copyOf(a, 5, a.getClass());
}
}
Итак, мой вопрос:

Какова необходимость уточнить этот первоначальный состав? :

Код: Выделить всё

(T[]) Arrays.copyOf(a, 5, a.getClass());
вместо простого действия (перед стиранием типа, во время кодирования):

Код: Выделить всё

Arrays.copyOf(a, 5, a.getClass());
Действительно ли это приведение необходимо для компилятора?

Хорошо, Arrays.copyOf возвращает Object [] и на них нельзя напрямую ссылаться более конкретным типом без явного приведения к понижению.

Но не может ли компилятор приложить усилия в этом случае, поскольку он имеет дело с обобщенным типом (возвращаемым типом!)?
Действительно, разве не достаточно того, что компиляторы применяют явное приведение к строке вызова метода? :

Код: Выделить всё

(String[])t.toArray(new String[4]);
ОБНОВЛЕНО------------------------------- --------------------------------------

Спасибо @ruakh за ответ.

Вот пример, который доказывает, что явное приведение, даже просто присутствующее во время компиляции, актуально:

Код: Выделить всё

public static void main(String[] args) {
Test t = new Test();
String[] newArray = t.toArray(new String[4]);
}

public  T[] toArray(T[] a) {
return (T[]) Arrays.copyOf(a, 5, Object[].class);
}
Приведение к T[] — единственный способ предупредить пользователя о том, что приведение может быть нерелевантным. И действительно, здесь мы получаем приведение Object[] к String[], что приводит к исключению ClassCastException во время выполнения.

Итак, если говорить о том, что «недостаточно того, что компиляторы применяют явное приведение к строке вызова метода», то ответ такой:

Разработчик не справляется с этим приведением, поскольку оно создается автоматически на этапе компиляции, поэтому эта функция времени выполнения не предупреждает пользователя о необходимости тщательно проверить свой код на предмет его безопасности ПЕРЕД запуском компиляции.

Короче говоря, этот актерский состав достоин внимания.

Подробнее здесь: https://stackoverflow.com/questions/136 ... h-generics
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «C#»