Question about how the C# Compiler emits TypeRef information
I found this interesting thing when I was trying out the new feature “optional parameters” in C# 4.0.
I know that there are two ways to use “optional parameters” in C# 4.0:
static void TestMethod(int parameter = 5) { }
static void TestMethod2([Optional, DefaultParameterValue(5)]int parameter) { }
Now if I compile this code and then view the assembly using IL Dasm, then I’ll see that in the “MetaInfo” window of IL Dasm, there is a type reference to OptionalAttribute like this:
Token: 0x01000002
ResolutionScope: 0x23000001
TypeRefName: System.Runtime.InteropServices.OptionalAttribute
MemberRef #1 (0a000001)
-------------------------------------------------------
Member: (0a000001) .ctor:
CallCnvntn: [DEFAULT]
hasThis
ReturnType: Void
No arguments.
But there is no sign of DefaultParameterValueAttribute. Why is that?
Actually I think the two attributes both should not be here, because they are treated differently by the compiler, they have their own flag values. To explain what I mean, please take a look at this:
Method #2 (06000002)
-------------------------------------------------------
MethodName: TestMethod (06000002)
Flags : [Private] [Static] [HideBySig] [ReuseSlot] (00000091)
RVA : 0x00002053
ImplFlags : [IL] [Managed] (00000000)
CallCnvntn: [DEFAULT]
ReturnType: Void
1 Arguments
Argument #1: I4
1 Parameters
(1) ParamToken : (08000002) Name : parameter flags: [Optional] [HasDefault] (00001010) Default: (I4) 5
Method #3 (06000003)
-------------------------------------------------------
MethodName: TestMethod2 (06000003)
Flags : [Private] [Static] [HideBySig] [ReuseSlot] (00000091)
RVA : 0x00002056
ImplFlags : [IL] [Managed] (00000000)
CallCnvntn: [DEFAULT]
ReturnType: Void
1 Arguments
Argument #1: I4
1 Parameters
(1) ParamToken : (08000003) 开发者_如何学JAVAName : parameter flags: [Optional] [HasDefault] (00001010) Default: (I4) 5
That is the metadata of the two methods. We can see that the last line of each code section already has the default parameter value stored, so why is OptionalAttribute still referenced?
This can be considered as a bug in the compiler. If you examine the assembly closely, there's nothing that references the OptionalAttribute TypeRef.
The TypeRef won't be present in the resulting assembly if you don't explicitely add in it TestMethod2. This simply shows that the attribute is added in a first pass, and later on removed. And it also shows that DefaultParameterValueAttribute is handled differently by the compiler.
Ultimately, this really is a small implementation detail, for instance, Mono's C# compiler won't produce a TypeRef for either attribute in the resulting assembly.
精彩评论