Когда компилятор встречает в коде операторы, которые определены над пользовательскими типами, он идет в таблицу методов этих типов и ищет там определение оператора, для каждого оператора генерируется свое имя(например, для оператора (+) - op_Addition, перегрузку этих методов поддерживает CLR, и в IL коде методы перегрузки генерируются с именами типа op_Addition
Перегруженные операторы должны быть определены в типе с которым взаимодействуют, а именно хотя бы один параметр в переопределении операторного метода должен иметь тип в котором объявлен, например вот такой код не скомпилируется:
, а вот такой скомпилируется
Как можно увидеть перегруженные операторные метода компилятор генерирует с модификатором specialname, это дает понять, что метод является перегрузкой
При перегрузке каждого оператора Microsoft рекомендует создавать в типе статический метод с предложенным ими именем(например, для + это Add
Тогда язык не поддерживающий перегрузку операторов сможет вызвать этот метод, но, по мнению Рихтера лучше было сделать так:
Позволить определять в языках не поддерживающих перегрузку метод с тем именем, с которым этот метод генерируется в IL, например метод с именем op_Addition для знака +, и отменить компиляцию перегруженных операторов с флагом specialname, тогда в c# программист сможет вызвать этот метод используя оператор +
implicit (неявное приведение типа) тогда, когда на тип не накладываются никакие ограничения, например приведение типа byte к int
explicit (явный cast) тогда, когда происходит ограничение типа, например приведение от long к int
Примеры implicit:
(Можно вызывать методы которые принимают параметр, в который определено преобразование определенного типа, c этим типом, перед вызовом этого метода вызовется implicit метод и его результат будет передан как параметр исходного метода
Также в спецификации языка указано, что если вы перегружаете, например, оператор ==, также нужно перегрузить оператор !=, так для всех противоположных операторов
В случаях перегрузок рекомендуется создавать либо конструкторы типов, если происходит приведение в тип, к котором определена перегрузка, либо методы с именем ToXXX, если для типа перегружен метод преобразование в тип XXX
Какие ограничения, наложенные на все методы компилятором C#, не выполняются при перегрузке методов преобразования
Эти два метода являются операторами приведения типа Pupil и типа Director тип Teacher, как видно компилятор генерирует методы с одинаковыми возвращаемыми значениям, именами но разными параметрами, такое разрешено CLR, но запрещено в C#
implicit оператор не работает при вызове Extension метода, через FluentInterface, но работает так: ExtensionClass.Extension(someThis,...parameters), а не так someThis.Extension(...parameters), при условии, что someThis, для someThis должен сработать explicit метод Это можно понять, Если бы компилятор стал искать все extension методы для всех типов, к которым возможно implicit приведение, но можно было бы войти в бесконечную рекурсию