F#/。NET空实例怪胎 [英] F# / .NET null instance oddity

查看:119
本文介绍了F#/。NET空实例怪胎的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这样的C#DLL:

I have this 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;
        }
    }
}

和本F#应用程序,它引用的DLL:

And this F# app which references the DLL:

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

没有人发起实例静态变量。你猜怎么着的F#应用程序的输出?

No-one initiates the Instance static variable. Guess what the output of the F# app is?


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

在一些测试中,我发现,除非我用(如访问实例字段),我不会得到NullReferenceExpcetion。

After a few tests I found out that unless I use this (e.g. to access instance field), I won't get NullReferenceExpcetion.

那是一个预期的行为或F#编译差距/ CLR?

Is that an intended behaviour or a gap in F# compilation / CLR?

推荐答案

我怀疑你会发现它的使用通话而不是 callvirt 如果你的IL。 C#编译器总是使用 callvirt ,即使对于非虚方法,因为它迫使一个无效的检查。

I suspect you'll find it's using call instead of callvirt if you look at the IL. The C# compiler always uses callvirt, even for non-virtual methods, because it forces a nullity check.

这是一个错误?好了,不一定。这取决于什么方法F#语言规范国家对空引用调用。这是完全可能的,它指出该方法将被调用(非虚拟)与空this引用,这正是发生了什么事。

Is this a bug? Well, not necessarily. It depends on what the F# language specification states about methods calls on null references. It's perfectly possible that it states that the method will be called (non-virtually) with a null "this" reference, which is exactly what has happened.

C#恰好说明,这类提领将抛出一个的NullReferenceException ,但是这是一个语言的选择。

C# happens to specify that this sort of dereferencing will throw a NullReferenceException, but that's a language choice.

我怀疑F#方法可能会快一点,由于缺乏无效的检查涉及...不要忘记,空引用不那么预期,在F#比C#...这的也许的解释不同的方式在这里拍摄。或者,它可能只是一个监督的,当然。

I suspect the F# approach may be a little faster, due to the lack of nullity checking involved... and don't forget that null references are less "expected" in F# than in C#... that may explain the different approach taken here. Or it could just be an oversight, of course.

编辑:我不是一个专家在阅读F#规范,但第6.9.6至少建议的,我认为这是一个错误:

I'm not an expert at reading the F# specification, but section 6.9.6 at least suggests to me that it's a bug:

6.9.6评价方法应用

6.9.6 Evaluating Method Applications

有关的方法阐述了应用,前pression的阐述形式将   无论是expr.M(参数)或M(参数)。

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

      
  • (可选)EXPR和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.

如果expr的计算结果为NULL,则NullReferenceException异常升高。

If expr evaluates to null then NullReferenceException is raised.

如果该方法是一个虚拟调度时隙(即,即宣告抽象的方法),则构件的主体根据expr的值的调度映射被选择

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.

这是否算作一个详细的应用程序或不有点超越我,我怕......但我希望这至少已有一定程度的帮助。

Whether this counts as an elaborated application or not is a little beyond me, I'm afraid... but I hope this has been at least somewhat helpful.

这篇关于F#/。NET空实例怪胎的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆