开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜