C#4.0の「オプションのパラメーター」機能は非常に興味深いものであることがわかったので、それらがどのように実現したかを理解しようとしました。だから私はこのようなメソッドを書きました:
private static void A(int a = 5) { }
コンパイルしてからILDASMで逆コンパイルします。これは、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#コンパイラーがメソッドAとB(名前を除く)に対してほぼ同じMSILコードを生成していることがわかりました。
ご覧のとおり、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
メソッド本体の2行目は、カスタム属性のctorを呼び出します。
だからこれは私の疑問につながります:
- [opt]はどういう意味ですか?メソッドAとBのパラメータの前に表示されるものを意味します。
- メソッドCがそのパラメーターに適用される属性のコンストラクターを呼び出すのに、メソッドAとBは呼び出さないのはなぜですか?
- メタデータにDefaultParameterValueAttributeの兆候が見つからないようですが、OptionalAttributeとMyTestAttributeは見つかります。何故ですか?足りないものはありますか?
前もって感謝します。