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

标签 c# .net compiler-construction metadata intermediate-language

我在尝试 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。

关于c# - 关于 C# 编译器如何发出 TypeRef 信息的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5645244/

相关文章:

c# - 我怎样才能保护字符串,例如C#

.net - EWS : Appoitnment Item. Id.UniqueId 不是常量

c++ - 编译器对循环进行向量化

compiler-construction - 这是 F# 编译器错误吗? #3

.net - VS2013中新的认证系统的LDAP支持(基于owin (owin.org))

c++ - 创建静态 C++ 库时出现问题

c# - 发送时服务器保持挂起状态

c# - 在 ASP.NET MVC 中从 ModelMetadataProvider 获取包含对象实例

c# - 如果收件人在一定时间内没有回复,则显示电子邮件提醒

c# - 关于 C# 的 TDD 和 Mocks 处理的书籍