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

Почему некоторый порядок применяется в общих ограничениях параметров?

При определении ограничений типа типового типа мы должны положить class() спереди и new() в конце, например.

Почему это, почему я не могу помещать свои ограничения в любом порядке?

Существуют ли какие-либо другие ограничения при заказе, кроме class/struct, сначала new() в конце?


Пример:

protected T Clone<T>() where T : class, ICopyable<T>, new()
4b9b3361

Ответ 1

Нет особой причины, почему этот заказ был выбран. Выбранный порядок идет от более общего к более конкретному, что, я полагаю, является достаточно приятным свойством.

Что касается вопроса "зачем вообще требовать заказ?", проще, чтобы команды по внедрению и тестированию имели четкий, недвусмысленный порядок, налагаемый языком. Мы могли бы позволить ограничениям прийти в любом порядке, но что это нас покупает?

Чем дольше я работаю на языках, тем больше я придерживаюсь мнения, что каждый раз, когда вы предоставляете пользователю выбор, вы даете им возможность сделать плохой выбор. Основной принцип проектирования С# заключается в том, что мы говорим вам, когда все выглядит неправильно и заставляет вас сделать их правильными - что не является основным принципом дизайна, скажем, JavaScript. Его основной принцип проектирования - "путаться и пытаться делать то, что имел в виду пользователь". Поместив больше ограничений на то, что является правильным синтаксисом в С#, мы можем лучше убедиться, что предполагаемая семантика хорошо выражена в программе.

Например, если бы я разрабатывал С# -пользовательский язык сегодня, у меня не было бы двусмысленных синтаксисов, например:

class C : X , Y

или

... where T : X, Y

Y явно предназначен для интерфейса. Является X? Мы не можем сказать синтаксически, должен ли X быть интерфейсом или классом. Достаточно сказать, что эта двусмысленность значительно усложняет такие вещи, как обнаружение циклов в базовых типах с интерфейсами и т.д. Было бы намного проще, если бы это было более подробно, как в VB.

Ответ 2

Как и большинство вопросов, связанных с синтаксисом, основной ответ заключается в том, что спецификация говорит так. Мы получаем следующую грамматику для ограничений общего типа из спецификации С# 5.0 (раздел 10.1.5)

параметры типа-параметра:

primary-constraint 
secondary-constraints
constructor-constraint 
primary-constraint   ,   secondary-constraints
primary-constraint   ,   constructor-constraint 
secondary-constraints ,   constructor-constraint 
primary-constraint   ,  secondary-constraints   ,   constructor-constraint 

первичного ограничение:

class-type 
class 
struct 

вторичные ограничения:

interface-type
type-parameter 
secondary-constraints   ,   interface-type
secondary-constraints   ,   type-parameter

конструктор-ограничение:

new (   )

Эрик Липперт отлично справился с объяснением, почему он был разработан таким образом, поэтому я не буду излагать это.