Skip to content

Instantly share code, notes, and snippets.

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

Как компилируются в IL методы с опциональными параметрами

Когда компилятор видит, что вызывается метод, который принимает больше параметров, чем ему передается, то он идет в метаданные модуля и смотрит, являются ли оставшиеся параметры опциональными Далее Рихтер пишет, что у этих параметров также есть атрибут DefaultParameterValue, в котором хранится значение по умолчанию и компилятор берет это значение и подставляет в вызывающий код, на в dotpeek я такой атрибут не нашел, тем не менее компилятор может проверить является ли этот атрибут опциональным и, если является, взять его значение из метаданных, кстати в IL коде метода с опциональными параметрами, также записываются default значения В итоге в IL коде происходит вызов со всеми заполненными параметрами:

Как происходит вызов метода с опциональными параметрами

Компилятор, когда встречает метод с недостающими параметрами, проверяет является ли они опциональными, если да - ищет их в методанных и явно проставляет в IL коде А вызов сам происходит как обычно

Какой IL код генерируется при вызове метода и передаче именованных параметров и каким образом он генерируется

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

Как в C# метод передаются параметры

Копируются, если это value type - то копируется значения, если reference type - указатель

В чем отличие ключевых слов ref и out

При использовании ключевого слова ref - компилятор ожидает, что параметр будет проинициализирован перед тем как отправлен в метод, out - что параметр будет проинициализирован уже внутри метода

Для чего могут применяться ключевые слова ref и out для ссылочных типов

Только если программист хочет чтобы указатель стал "указывать" на другой объект в памяти, т.к, если не использовать ref или out в метод передается копия указателя, по которой можно мутировать объект, но если присвоить этому указателю ссылку на другой объект, то смысла в этом не будет, т.к указатель из вызывающего метода останется таким же, поэтому если программист хочет явно отвязать указатель от одного объекта к другому, то ему нужно использовать ref

Как работают ключевые слова ref и out для значимых и ссылочных типов

В обоих случаях параметр помеченный, как ref или out передается либо значения(value type), либо указатель на указатель объекта в куче(reference type)

Почему можно объявить вот такие два метода:

        public void One(int t)
        {
            
        }
        
        public void One(ref int t)
        {
            
        }

А вот такие два нельзя:

        public void One(ref int t)
        {
            
        }
        
        public void One(out int t)
        {
            
        }

В первом случае, потому что IL код полученных методов отличается, вот таким образом: В верхнем методе передается значение переменной, а перед типом стоит & - указывающий, что идет работа с адресом в памяти этого объекта, а не с его значением Во втором случае в IL получаются методы с одинаковыми сигнатурами, потому что для CLR все-равно какое ключевое слово используется, потому что сделать нужно одно и тоже, передать указатель на переменную в стеке, это может быть как значение - value type, так и указатель - reference type, разницу между словами ref и out остлеживает только компилятор

Почему необходимо явно приводить переменные к типу, если они передаются как ref или out параметр

Потому что возможны вот такие конфузы(если бы этот код компилировался) Т.e можно бы было поменять тип объекта, поэтому в методы с параметрами ref и out нужно посылать максимально точный тип

Привести пример метода Swap для ссылочных типов

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