Мне показалась очень интересной функция «необязательных параметров» в C # 4.0, поэтому я попытался выяснить, как они это сделали.
поэтому я написал такой метод:
private static void A(int a = 5) { }
Скомпилировал, затем декомпилировал в IL DASM, это код IL:
.method private hidebysig static void A([opt] int32 a) cil managed
{
.param [1] = int32(0x00000005)
// Code size 2 (0x2)
.maxstack 8
IL_0000: nop
IL_0001: ret
} // end of method Program::A
И оно имеет это в своих метаданных:
(1) ParamToken: (08000002) Имя: флаги: [Необязательно] [HasDefault] (00001010) По умолчанию: (I4) 5
Итак, я последовал подсказке и написал такой метод:
private static void B([Optional, DefaultParameterValue(78)]int b) { }
Скомпилировал и декомпилировал, и я обнаружил, что компилятор C # сгенерировал практически идентичный код MSIL для методов A и B (кроме имени).
Как мы видим, в коде IL нет никаких признаков атрибутов, и он чувствовал себя не так, поэтому я написал собственный атрибут, подобный этому:
[AttributeUsage(AttributeTargets.Parameter)]
public class MyTestAttribute : Attribute
{
}
Затем использовал его в методе C следующим образом:
private static void C([MyTest]int c) { }
Скомпилировал, а затем декомпилировал, и хах, я нашел это:
.method private hidebysig static void C(int32 c) cil managed
{
.param [1]
.custom instance void ConsoleApplication1.MyTestAttribute::.ctor() = ( 01 00 00 00 )
// Code size 2 (0x2)
.maxstack 8
IL_0000: nop
IL_0001: ret
} // end of method Program::C
Вторая строка тела метода вызывает ctor моего пользовательского атрибута.
Так что это приводит к моим сомнениям:
- Что означает [opt]? Я имею в виду тот, который появляется перед параметром метода A и B.
- Почему метод C вызывает конструктор Атрибута, который применяется к его параметру, а методы A и B - нет?
- Я не могу найти никаких признаков DefaultParameterValueAttribute в метаданных, но я могу найти OptionalAttribute и MyTestAttribute. Это почему? Я что-то упускаю?
Заранее спасибо.