Попытка неявного преобразования группы методов (часть 2)

Упрощенный из этого вопроса и избавлен от возможного воздействия LinqPad (без лишнего смысла), простого консольного приложения, подобного этому:

public class Program
{
    static void M() { }    
    static void Main(string[] args)
    {
        Action a = new Action(M);
        Delegate b = new Action(M);
        Console.WriteLine(a == b);      //got False here
        Console.Read();
    }        
}

"false" - результат оператора ceq в CIL приведенного выше кода (подробности см. в исходном вопросе). Итак, мои вопросы:

(1) Почему == переводится в ceq вместо call Delegate Equals ?

Здесь я не заботиться о (отмене) переноса между Delegate и Action. Наконец, при вычислении a == b , a имеет тип Action , а b - Делегат . Из спецификации:

7.3.4 Разрешение перегрузки двоичного оператора

Операция вида x op y, где op - перегружаемый двоичный оператор, x - выражение типа X, а y является выражением типа Y, обрабатывается следующим образом:

• Набор пользовательских операторов-кандидатов, предоставляемых X и Y для определяется оператор операции op (x, y). Набор состоит из объединение операторов-кандидатов, предоставленных X и кандидатом операторы, предоставляемые Y, каждый из которых определяется с использованием правил §7.3.5. Если X и Y относятся к одному типу, или если X и Y являются производными от общего базовый тип, то общие операторы-кандидаты встречаются только в комбинированном установить один раз.

• Если набор возможных пользовательских операторов не пусто, то это становится набором операторов-кандидатов для операция. В противном случае предопределенный бинарный оператор op реализации, включая их поднятые формы, становятся набором кандидаты операторов на операцию. Предопределенные реализации данного оператора указаны в описании оператора (С §7.8 по §7.12).

• Правила разрешения перегрузки в §7.5.3: применяется к набору операторов-кандидатов для выбора лучшего оператора относительно списка аргументов (x, y), и этот оператор становится результат процесса разрешения перегрузки. Если разрешение перегрузки не удается выбрать один лучший оператор, возникает ошибка времени привязки.

7.3.5 Кандидаты в определяемые пользователем операторы

Для данного типа T и оператора операции op (A), где op - это перегружаемый оператор, а A - список аргументов, набор возможных пользовательских операторов, предоставляемых T для оператора op (A) определяется следующим образом:

• Определить тип T0. Если T является типом, допускающим значение NULL, T0 является его базовым типом, в противном случае T0 равно T.

• Для всех объявлений оператора op в T0 и всех снятых формы таких операторов, если применим хотя бы один оператор (§7.5.3.1) относительно списка аргументов A, то набор Операторы-кандидаты состоят из всех таких применимых операторов в T0.

• В противном случае, если T0 является объектом, набор операторов-кандидатов пуст.

• В противном случае набор операторов-кандидатов, предоставленный T0, является набором операторов-кандидатов, предоставляемых прямым базовым классом T0, или эффективный базовый класс T0, если T0 является параметром типа.

Согласно спецификации, a и b имеют один и тот же базовый класс Delegate , очевидно, здесь должно применяться правило оператора == , определенное в Delegate ( operator == по существу вызывает Delegate.Equals). Но теперь похоже, что список кандидатов определяемых пользователем операторов пуст и, наконец, применен Object == .

(2) Должен ли (подчиняться) код FCL спецификации языка C #? Если нет, то мой первый вопрос не имеет смысла, потому что что-то специально лечится. И затем мы можем ответить на все эти вопросы, используя «о, это особый подход в FCL, они могут делать то, что мы не можем. Спецификация предназначена для внешних программистов, не говорите глупостей».

14
задан Community 23 May 2017 в 11:48
поделиться