Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 反射使用哪种调用约定。发射?_C#_.net_Cil_Reflection.emit - Fatal编程技术网

C# 反射使用哪种调用约定。发射?

C# 反射使用哪种调用约定。发射?,c#,.net,cil,reflection.emit,C#,.net,Cil,Reflection.emit,这里的介绍性指南说,基本上任何东西都可以使用调用conventions.Standard: 另一方面,MSDN为调用约定说明了这一点。标准: 指定由公共语言运行库确定的默认调用约定。对静态方法使用此调用约定。例如,实例或虚拟方法使用这个 因此,我假设我应该听MSDN,并且只对静态方法使用Standard。但是,对于实例方法,它是如何工作的呢?有什么区别 编辑: 以下是一些来自实验的更多信息: 使用HasThis或Standard生成的构造函数似乎总是生成反映Standard的方法 使用Has

这里的介绍性指南说,基本上任何东西都可以使用
调用conventions.Standard

另一方面,MSDN为调用约定说明了这一点。标准:

指定由公共语言运行库确定的默认调用约定。对静态方法使用此调用约定。例如,实例或虚拟方法使用这个

因此,我假设我应该听MSDN,并且只对静态方法使用
Standard
。但是,对于实例方法,它是如何工作的呢?有什么区别

编辑: 以下是一些来自实验的更多信息:

  • 使用
    HasThis
    Standard
    生成的构造函数似乎总是生成反映
    Standard
    的方法
  • 使用
    HasThis
    生成的实例方法反映到
    HasThis
    和使用
    Standard
    生成的实例方法反映到
    Standard | HasThis
  • “静态”代码编译定义的实例方法反映到
    标准| HasThis

所以结论是我应该始终使用
标准
?老实说,仍然没有看到任何区别,因为这两种方法都有效。

在定义静态方法时使用标准

在定义实例方法时使用标准| hasship


Standard基本上告诉.NET使用CLR Fastcall,而HasThis则告诉编译器在第一个参数中传递一个隐藏的this*。

我猜这里的主要区别在于如何处理空值,多态性是否工作,以及反射API是否将arg0计算为参数。你有没有试过看看如果你对一个空实例调用它会发生什么?@MarcGravel我不确定我是否正确理解你的意思。您的意思是尝试对空实例调用静态方法吗?但是静态方法没有问题;它们应该清楚地用CallingConventions.Standard.no生成;我的意思是:对instance方法进行委托,并使用null目标调用它。使用错误的调用约定,这可能会起作用-如果“this”为空。@MarcGravel现在我明白了。试过之后,它抱怨说有一个TargetException。它需要一个非静态方法的目标。所以这两种方法似乎都有效。@relative_random-我怀疑确切的行为将取决于该方法是否是通过call而不是callvirt调用的。这只是没有必要的,MethodBuilder足够聪明,可以单独为实例方法添加HasThis@HansPassant—如果人们遵循上述答案,那么您链接的实现中的保护代码就没有必要了。只是说说而已+1尽管用于链接实施细节。