cil - MSIL 方法中 hidebysig 的用途是什么?

标签 cil

使用 ildasm 和 C# 程序,例如

static void Main(string[] args)
{

}

给出:

.method private hidebysig static void  Main(string[] args) cil managed
{
  .entrypoint
  // Code size       2 (0x2)
  .maxstack  8
  IL_0000:  nop
  IL_0001:  ret
} // end of method Program::Main

hidebysig 构造有什么作用?

最佳答案

来自ECMA 335 ,分区 1 第 8.10.4 节:

The CTS provides independent control over both the names that are visible from a base type (hiding) and the sharing of layout slots in the derived class (overriding). Hiding is controlled by marking a member in the derived class as either hide by name or hide by name-and-signature. Hiding is always performed based on the kind of member, that is, derived field names can hide base field names, but not method names, property names, or event names. If a derived member is marked hide by name, then members of the same kind in the base class with the same name are not visible in the derived class; if the member is marked hide by name-and-signature then only a member of the same kind with exactly the same name and type (for fields) or method signature (for methods) is hidden from the derived class. Implementation of the distinction between these two forms of hiding is provided entirely by source language compilers and the reflection library; it has no direct impact on the VES itself.

(目前还不清楚,但 hidebysig 的意思是“通过姓名和签名隐藏”。)

也在分区 2 的第 15.4.2.2 节中:

hidebysig is supplied for the use of tools and is ignored by the VES. It specifies that the declared method hides all methods of the base class types that have a matching method signature; when omitted, the method should hide all methods of the same name, regardless of the signature.

举个例子,假设您有:

public class Base
{
    public void Bar()
    {
    }
}

public class Derived : Base
{
    public void Bar(string x)
    {
    }
}

...

Derived d = new Derived();
d.Bar();

这是有效的,因为 Bar(string) 不会隐藏 Bar(),因为 C# 编译器使用 hidebysig。如果它使用“按名称隐藏”语义,则您根本无法对 Derived 类型的引用调用 Bar(),尽管您仍然可以对其进行强制转换到 Base 并这样调用它。

编辑:我刚刚尝试过将上述代码编译为 DLL,对其进行 ildasming,删除 Bar()Bar(string ),再次对其进行 ilasming,然后尝试从其他代码调用 Bar():

Derived d = new Derived();
d.Bar();

Test.cs(6,9): error CS1501: No overload for method 'Bar' takes '0' arguments

但是:

Base d = new Derived();
d.Bar();

(没有编译问题。)

关于cil - MSIL 方法中 hidebysig 的用途是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/656325/

相关文章:

c# - 永远不会调用覆盖相等运算符

c# - 调用堆栈和评估堆栈如何关联?

C# 发出对泛型方法的调用

.net - 为 .net 编写编译器 - IL 还是字节码?

compiler-construction - 从哪里获得 F# ILX2CIL 汇编程序?

c# - 适本地发出属性(property)

clr - 处理阵列时我应该固定什么?

.net - .Net等效于x86 ASM命令XADD

c# - CIL - 装箱/拆箱与可空

reflection - 如何发送到具有 'params' 构造函数的类?