gpt4 book ai didi

c# - 扩展方法和成员方法 : why each is implemented differently by compilers (internally)?

转载 作者:太空狗 更新时间:2023-10-29 23:33:59 26 4
gpt4 key购买 nike

考虑这段代码:

 A a = null;
a.f(); //Will it throw NullReferenceException?

上面会抛出NullReferenceException吗?

答案是:这取决于 f() 是什么。

这种差异引出了一个问题:C# 编译器如何实现和查看每种类型的方法?另外,为什么成员方法必须抛出异常即使它不访问任何成员数据?似乎 C# 编译器提前假设成员方法将访问成员数据,因此如果对象为 null 则抛出异常,因为无法访问使用 null 对象的成员数据。但是,在扩展方法的情况下,它会推迟此决定,直到它实际尝试使用空引用访问成员数据,only then it throws exception .

我的理解在多大程度上是正确的?如果是这样,为什么会有这种差异?

是的,我知道如果f()是一个扩展方法,那么a.f()就相当于写AExt.f(a),所以后者在使用 a 访问成员之前不应抛出异常。但我的重点主要放在编译器实现上(它甚至可以以相同的方式实现成员方法)。

最佳答案

是的,这就是这段代码的行为方式(如果扩展方法不检查 null 并自行抛出异常)。在 null 上调用非虚拟实例方法是对的可以工作,如果该方法不访问类的任何实例字段(直接或间接)。

但是the language designers felt this would be confusing , 所以他们确保对象不是 null通过使用 callvirt IL指令。

有了扩展方法,这就不会那么令人困惑了(没有人期望 thisnull ,但应该检查声明为 this IEnumerable<TSource> source 的参数)。你可以像普通静态方法一样调用扩展方法,所以它应该检查 null反正。此外,调用该函数的两种方式的行为可能应该完全相同。

关于c# - 扩展方法和成员方法 : why each is implemented differently by compilers (internally)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7295419/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com