Подтвердить что ты не робот

Почему генераторы С# не могут быть получены из одного из параметров типового типа, как они могут, в шаблонах С++?

Почему генераторы С# не могут быть получены из одного из параметров типового типа, как они могут в шаблонах С++? Я имею ввиду, что это невозможно, потому что CLR не поддерживает это, но почему?

Я знаю о глубоких различиях между шаблонами С++ и С# generics - первые являются компиляционными сущностями и должны быть разрешены во время компиляции, в то время как последние являются сущностями класса первого класса.

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

EDIT:

Я хотел бы знать о проблеме с жестким ядром, которая дает такую ​​высокую цену при реализации этой функции, которая оправдывает ее еще не реализованную. Например, рассмотрите это вымышленное выражение:

class C<T> : T
{
}

Как заметил Эрик Липперт, если " Что, если T - это структура? Что, если T - тип закрытого класса? Что, если T - тип интерфейса? Что, если T - C?! Что, если T является класс, зависший от C? Что, если T - абстрактный тип с абстрактным методом? Что делать, если T имеет меньшую доступность, чем C? Что, если T - System.ValueType? (Можете ли вы иметь неструктуру, которая наследуется от System.ValueType?) Как насчет System.Delegate, System.Enum и т.д."

Как продолжает Эрик, " Это простые, очевидные. Действительно, он прав. Меня интересует конкретный пример не простой, ни очевидной проблемы, которую трудно решить.

4b9b3361

Ответ 1

Хорошо, сначала спросите себя, что может пойти не так с class C<T> : T { }. На ум сразу приходит огромное количество вещей:

Что, если T - структура? Что, если T - тип закрытого класса? Что, если T - тип интерфейса? Что, если T C<T>?! Что, если T - класс, полученный из C<T>? Что, если T - абстрактный тип с абстрактным методом? Что делать, если T имеет меньшую доступность, чем C? Что, если T - System.ValueType? (Можете ли вы иметь неструктуру, которая наследуется от System.ValueType?) Что относительно System.Delegate, System.Enum и т.д.?

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

Расходы будут огромными, поэтому преимущество будет огромным. Я не вижу здесь огромной пользы.

Ответ 2

Хорошо, если вам не понравился мой предыдущий ответ, тогда пусть другой подход.

Ваш вопрос предполагает ложь: нам нужна причина не реализовывать функцию. Напротив, нам нужна очень и очень хорошая причина для реализации любой функции. Особенности чрезвычайно дороги в их первоначальных расходах, их эксплуатационных расходах и в альтернативных издержках. (То есть, время, которое вы тратите на функцию X, - это время, которое вы не можете потратить на выполнение функции Y, и это может помешать вам когда-либо делать функцию Z.) Чтобы ответственно доставлять ценность нашим клиентам и заинтересованным сторонам, мы не можем реализовать каждую функцию что кому-то нравится.

Это не до дизайнеров среды выполнения, чтобы оправдать, почему они не реализовали функцию, которую вы считаете особенно приятной. Особенности приоритеты основаны на их затратах и ​​выгодах для пользователей, и пользователи точно не стучат по моей двери, требуя такого рода наследования. Эта особенность значительно изменила бы то, как анализ системы типов работает во время выполнения, имеет далеко идущие последствия для каждого языка, который потребляет дженерики, и, как мне кажется, дает очень мало пользы.

Мы используем этот вид наследования в компиляторе - написанный на С++ - и полученный код трудно поддаться, трудно поддерживать и запутывать для отладки. Я прилагаю все усилия, чтобы постепенно исключить такой код. Я против того, чтобы включить одинаковые типы ошибок в С#, если для этого не существует огромной выгоды.

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

Ответ 3

Пример кода, где это может помочь:

public class SpecialDataRow<T> : T where T : DataRow
{
    public int SpecialFactor { get; set; }
}

Это позволит создавать "специальные" строки из DataRow, а также из любых полученных DataRows (например, с помощью набора типизированных наборов данных)

Я не вижу другого способа, как закодировать такой класс

Ответ 4

Что было бы так полезно в этом вопросе?

Помните, что, несмотря на имя, дженерики никогда не предназначались для поддержки общего программирования.

Чтобы поддерживать такую ​​функцию, им пришлось бы внести некоторые существенные изменения в CLR.

Вам нужно будет определить класс, который происходит от типа, который даже не существует во время компиляции.

Почему они должны прыгать через такие обручи и довольно принципиально компрометировать их систему типов, чтобы добавить эту функцию? Стоит ли это?

Если вы так думаете, скажите им, почему. Напишите отзыв на сайте connect.microsoft.com о том, почему эта функция настолько фундаментальна, что ее необходимо добавить.

Ответ 5

Шаблоны С++ не могут сравниваться с генераторами С#. Шаблоны С++ предварительно обрабатываются как макросы, в то время как generics в .NET обрабатываются средой выполнения.

Но есть и другие люди, которые знают об этом гораздо больше, чем я...