Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save eterekhin/46f1b1cb39432cda0d91ff453502e102 to your computer and use it in GitHub Desktop.
Save eterekhin/46f1b1cb39432cda0d91ff453502e102 to your computer and use it in GitHub Desktop.

Как компилятор вызывает перегруженные операторы

Когда компилятор встречает в коде операторы, которые определены над пользовательскими типами, он идет в таблицу методов этих типов и ищет там определение оператора, для каждого оператора генерируется свое имя(например, для оператора (+) - op_Addition, перегрузку этих методов поддерживает CLR, и в IL коде методы перегрузки генерируются с именами типа op_Addition

Какие ограничения накладываются на перегрузку операторов

Перегруженные операторы должны быть определены в типе с которым взаимодействуют, а именно хотя бы один параметр в переопределении операторного метода должен иметь тип в котором объявлен, например вот такой код не скомпилируется: , а вот такой скомпилируется

Как выглядят перегруженные операторы в генерируемом IL коде

Как можно увидеть перегруженные операторные метода компилятор генерирует с модификатором specialname, это дает понять, что метод является перегрузкой

Какие правила определены Microsoft для перегрузки операторов, используемых из других языков

При перегрузке каждого оператора Microsoft рекомендует создавать в типе статический метод с предложенным ими именем(например, для + это Add Тогда язык не поддерживающий перегрузку операторов сможет вызвать этот метод, но, по мнению Рихтера лучше было сделать так: Позволить определять в языках не поддерживающих перегрузку метод с тем именем, с которым этот метод генерируется в IL, например метод с именем op_Addition для знака +, и отменить компиляцию перегруженных операторов с флагом specialname, тогда в c# программист сможет вызвать этот метод используя оператор +

Когда нужно использовать implicit, а когда explicit оператор

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 приведение, но можно было бы войти в бесконечную рекурсию

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment