有关C#编译器如何发出TypeRef信息的问题

问题描述

|| 当我在C#4.0中尝试新功能“可选参数”时,发现了一件有趣的事情。 我知道在C#4.0中使用“可选参数”有两种方法:
static void TestMethod(int parameter = 5) { }
static void TestMethod2([Optional,DefaultParameterValue(5)]int parameter) { }
现在,如果我编译此代码,然后使用IL Dasm查看程序集,那么我将在IL Dasm的“ MetaInfo”窗口中看到对OptionalAttribute的类型引用,如下所示:
Token:             0x01000002
ResolutionScope:   0x23000001
TypeRefName:       System.Runtime.InteropServices.OptionalAttribute
MemberRef #1 (0a000001)
-------------------------------------------------------
    Member: (0a000001) .ctor: 
    CallCnvntn: [DEFAULT]
    hasThis 
    ReturnType: Void
    No arguments.
但是没有DefaultParameterValueAttribute的迹象。 这是为什么? 实际上,我认为这两个属性都不应该在此处,因为编译器对它们的处理方式有所不同,它们具有自己的标志值。要解释我的意思,请查看以下内容:
    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) Name : parameter flags: [Optional] [HasDefault]  (00001010) Default: (I4) 5
那就是这两种方法的元数据。我们可以看到每个代码段的最后一行已经存储了默认参数值,那么为什么仍然引用OptionalAttribute?     

解决方法

这可以视为编译器中的错误。如果仔细检查程序集,则没有引用OptionalAttribute TypeRef的内容。 如果您没有显式添加TestMethod2,TypeRef将不会出现在结果程序集中。这仅表明该属性是在第一遍添加的,之后又被删除了。它也表明DefaultParameterValueAttribute由编译器以不同的方式处理。 最终,这确实是一个很小的实现细节,例如,Mono \的C#编译器不会为所得程序集中的任何一个属性生成TypeRef。     

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...