繁体   English   中英

C#中“ this”的含义是什么?

[英]What's the meaning of 'this' in C#?

在“通过C#执行CLR”的第170页上:


public sealed class Program {
    public Int32 GetFive() { return 5; }
    public static void Main() {
       Program p = null;
       Int32 x = p.GetFive(); // In C#, NullReferenceException is thrown
    }
}

从理论上讲,上面的代码很好。 当然,变量p为null,但是在调用非虚拟方法(GetFive)时,CLR仅需要知道p的数据类型,即Program。 如果确实调用了GetFive,则此参数的值将为null。 由于在GetFive方法中未使用该参数,因此不会引发NullReferenceException。


请原谅我的愚蠢。 我记得CLR通过'this'定位真正的方法代码,它总是隐式地出现在方法delcare的第一个参数上,为什么它说'当调用非虚拟方法(GetFive)时,CLR只需要知道p的数据类型'?

CLR不会对非虚拟方法进行null检查。 基本上,如果使用call指令call方法,则CLR不会检查this指针是否为null。 相反, callvirt指令始终检查无效性。 但是,无论该方法是否为虚拟方法,C#都会发出callvirt指令。

这段话说的是,如果C#编译器针对非虚拟方法发出了语义上更合适的call指令,而不是callvirt指令,那么所讨论的代码将不会抛出NullReferenceException 我记得,编译器团队决定几乎总是发出callvirt指令,因为它更好地处理了版本控制(而且JIT可以将callvirt优化为call )。

参见http://www.pvle.be/tag/clr/

this是指自身(类)的当前实例。

您的代码段,

Program p = null;
Int32 x = p.GetFive(); // In C#, NullReferenceException is thrown

之所以不起作用,是因为您试图调用null GetFive方法(一个不存在的Program实例)-换句话说,您试图敲开一个无效的门,一个不存在的门。 由于CLR不知道门的位置,因此抛出异常“找不到功能门!”。 对您来说-比不确定的行为要好得多。

好的。 我只是通过C#(第3版)查阅了CLR的170页。

页面的整个重点可能是“ 重要”部分,另一个CLR语言编译器会在该部分中生成一些使用C#类的代码,然后将C#代码更改为非虚拟方法,而无需重新编译引用C#库的代码。 在这种情况下,您可能会遇到问题,具体取决于调用者是实现call还是callvirt(尚未定义编译器将执行的操作)。

c#始终默认为callvirt,因此在那里没有问题,但是对于调用方,您可能无法提前知道。 如果这样做,则在运送库或API时可能会无意中破坏其他人的程序。


试试这个吧。

    public static Int32 GetFive() { return 5; }    
    public static void Main() {       
        Int32 x = GetFive(); 
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM