c# – F#/ .NET null实例奇怪

前端之家收集整理的这篇文章主要介绍了c# – F#/ .NET null实例奇怪前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有这个C#DLL:
namespace TestCSProject
{
    public class TestClass
    {
        public static TestClass Instance = null;

        public int Add(int a,int b)
        {
            if (this == null)
                Console.WriteLine("this is null");
            return a + b;
        }
    }
}

而这个引用DLL的F#应用程序:

open TestCSProject
printfn "%d" (TestClass.Instance.Add(10,20))

无人启动Instance静态变量.猜猜F#应用的输出是什么?

this is null
30
Press any key to continue . . .

经过几次测试,我发现除非我使用这个(例如访问实例字段),否则我不会得到NullReferenceExpcetion.

这是F#编译/ CLR中的预期行为还是间隙?

解决方法

我怀疑你会发现它正在使用call而不是callvirt,如果你看看IL. C#编译器始终使用callvirt,即使是非虚拟方法,因为它强制执行无效检查.

这是一个bug吗?嗯,不一定这取决于F#语言规范对空引用的方法调用的说明.它完全可以说,该方法将被称为(非虚拟),使用null“this”引用,这正是发生了什么.

C#碰巧指定这种取消引用将抛出NullReferenceException,但这是一种语言选择.

我怀疑F#方法可能会更快一点,因为缺乏无效检查涉及…并且不要忘记,空引用在F#中比在C#中更少的“预期”,这可能解释了采用的不同方法这里.或者它当然可以是一个监督.

编辑:我不是阅读F#规范的专家,但第6.9.6节至少对我来说,这是一个错误

6.9.6 Evaluating Method Applications

For elaborated applications of methods,the elaborated form of the expression will be
either expr.M(args) or M(args).

  • The (optional) expr and args are evaluated in left-to-right order and the body of the member is evaluated in an environment with formal parameters that are mapped to corresponding argument values.

  • If expr evaluates to null then NullReferenceException is raised.

  • If the method is a virtual dispatch slot (that is,a method that is declared abstract) then the body of the member is chosen according to the dispatch maps of the value of expr.

无论这是否是一个精心设计的应用程序,都是有点超出我的,我害怕…但我希望这至少有一些帮助.

猜你在找的C#相关文章