C # Language Design: группа методов внутри оператора `is` - PullRequest
27 голосов
/ 13 июля 2010

Мне интересны некоторые варианты дизайна языка C #.В спецификации C # есть правило, которое позволяет использовать группы методов в качестве выражений оператора is:

class Foo {
  static void Main() { if (Main is Foo) Main(); }
}

Условие выше всегда ложно, как указано в спецификации:

7.10.10 Оператор is

Если E является группой методов или литералом NULL, если тип E является ссылочным типом или типом NULL, азначение E равно нулю, результат равен false.

Мои вопросы: Какова цель / точка / причина разрешения использовать элемент языка C # безпредставление во время выполнения в CLR, как группы методов внутри такого оператора «выполнения», как is?

Ответы [ 2 ]

21 голосов
/ 13 июля 2010

Какова цель / точка / причина, позволяющая использовать элемент языка C # без представления среды выполнения в CLR, как группы методов внутри такого оператора "времени выполнения", как есть?

В архиве проектных заметок не упоминается, почему было принято это решение, поэтому любое предположение об ответе будет предположительным. Они упоминают, что если результат «есть» может быть определен статически, чтобы всегда быть истинным или ложным, то он будет определен таким образом и выдаст предупреждение. Кажется вероятным, что это может быть просто ошибкой.

Самая распространенная причина превращения того, что по праву может быть ошибкой, в предупреждение (или просто его разрешение) заключается в том, что это уменьшает нагрузку на производителей программ, которые автоматически генерируют код. Однако я не вижу здесь действительно убедительного сценария.

ОБНОВЛЕНИЕ:

Я только что проверил спецификацию C # 1.0. В нем нет этого языка. Он ничего не говорит о пустых значениях или аргументах группы методов. И, конечно, ничего не говорится о преобразованиях групп методов, потому что в C # 1.0 не было неявных преобразований групп методов; вам пришлось явно вызывать «new D (M)», если вы хотите преобразовать метод M в делегировать тип D.

Этот последний пункт является оправданием для "M is D", возвращающего ложь, а не истину; Вы не могли бы по закону сказать "D d = M;" так почему «М есть Д» должно быть правдой?

Конечно, в C # 2.0 это имеет меньше смысла, поскольку вы можете сказать "D d = M;" в C # 2.0.

Я также только что спросил одного из присутствующих людей, когда был разработан оператор «is», и он не помнил, чтобы когда-либо решал этот вопрос так или иначе. Он подозревал, что оригинальная конструкция оператора «is» заключалась в том, чтобы не выдавать никаких ошибок, только предупреждения, и что весь текст в спецификации о том, что делать с группами методов и пустыми значениями и еще много чего, был добавлен пост-hoc для Версия спецификации C # 2.0 и основана на том, что на самом деле сделал компилятор.

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

Эта теория подкрепляется тем фактом, что анонимные методы do приводят к ошибке при использовании в качестве аргумента "is" в C # 2.0. Это не было бы критическим изменением, но это будет критическим изменением, заставляющим "M is D" внезапно начать возвращать истину или быть ошибкой.

ДОПОЛНИТЕЛЬНОЕ ОБНОВЛЕНИЕ:

Исследуя это, я узнал кое-что интересное. (Для меня.) Когда функция была изначально разработана, она должна была разрешать либо имя типа, , либо объект Type в качестве правого аргумента для «is». Эта идея была заброшена задолго до C # 1.0.

3 голосов
/ 13 июля 2010

Прежде всего, метод не является типом, msdn четко гласит следующее:

Оператор is is используется для проверки является ли тип времени выполнения объекта совместим с данным типом

Пример

public static void Test (object o) 
{
   Class1 a;

   if (o is Class1) {}
}

От MSDN:

Выражение is принимает значение true, если выполняются оба следующих условия:

  • выражение не является нулевым.
  • выражение может быть приведено к типу. То есть приведенное выражение формы (типа) (выражения) будет завершено без исключения. Для получения дополнительной информации см. 7.6.6 Выражения приведения.

Таким образом, причина того, что ваш пример ложный, касается второй точки, он должен быть приведен к определенному типу.

Надеюсь, я не правильно понял вопрос.

...