为什么is运算符在给定null时返回false?

在我看来,该is运营商是有点不一致。

bool Test()
{
    // Returns false, but should return true.
    return null is string;
}

人们希望null值属于任何引用(或可为空)的类型。 事实上,C#语言规范说明了一些支持该假设的内容,例如(6.1.6隐式引用转换):

隐式引用转换是:
...
•从null文字到任何引用类型。

说明(7.10.10 is运算符)的is通过说表达式运算符开始(E is T)将导致真正的当从引用转换ET存在,但随后笔者通过明确排除的情况下继续当Enull字符或具有null值时。

他们为什么这样做? 对我来说,这似乎违反直觉。


这个问题是我的博客在2013年5月30日的主题。谢谢你的好问题!


你正盯着一条空的车道。

有人问你:“你的车道上可以放一辆本田思域?”

是。 是的,它可以。

有人在第二个车道指向你。 它也是空的。 他们问:“我车道的当前内容是否适合你的车道?”

是的,很明显。 两条车道都是空的! 很明显,一个人的内容可以适合另一个人,因为没有任何内容。

有人问你:“你的车道是否包含本田思域?”

不,不是的。

你认为is运算符回答第二个问题:给定这个值,它是否适合该类型的变量? 空引用是否适合这种类型的变量? 是的,它确实。

这不是问题的is运营商的答案。 现在的问题是, is运营商的答案是第三个问题。 y is X不问“是y类型的变量的合法值X ?” 它要求“是y至类型的对象的有效引用X ?” 由于空引用不是对任何类型的任何对象的有效引用,所以答案是“否”。 那条车道是空的; 它不包含本田思域。

另一种看待它的方式是y is X回答“如果我把y as X表示y as X ,我会得到一个非空结果吗?如果y为空,显然答案是否定的!


更深入地看待你的问题:

人们希望空值属于任何引用(或可为空)的类型

我们可以隐式地假设一个类型是一组值,并且值y与变量类型X的赋值兼容性不过是检查y是否是set x的成员。

尽管这是查看类型的一种非常常见的方式,但这不是查看类型的唯一方式,也不是C#查看类型的方式。 空引用是C#中没有类型的成员; 赋值兼容性不仅仅是检查一个集合是否包含一个值。 仅仅因为空引用与引用类型X的变量赋值兼容并不意味着null是类型X的成员。“赋值兼容”关系和“是类型成员”关系显然有很多重叠,但在CLR中它们不相同。

如果关于类型理论的思考对你感兴趣,请查看我最近关于这个主题的文章:

你称之为“类型”的是什么? 第一部分

你称之为“类型”的是什么? 第二部分


null文字可以被分配给任何引用类型。 它本身不是一种类型。 它是表示空引用的特殊字面值。

在这种情况下is将返回truenull将被传递中,你将能够用做null的文字? 没有 - 它是null 。 除了令人困惑的事情之外,它的true意义是什么?


无论如何 - 就直觉而言,阅读英文代码并告诉我:

null is string;

当我看到这个问题时,它似乎在问这个问题is "nothing" a string? 。 我的直觉告诉我,不,它不是 - nothing


我认为null is string返回false是非常直观的。 空无意义,绝对不是一个字符串。 所以它应该返回false。 虽然这是语言设计师所做的选择,但当您考虑null的真实世界含义时,这是非常直观的选择。

链接地址: http://www.djcxy.com/p/57957.html

上一篇: Why does the is operator return false when given null?

下一篇: How the right associative of null coalescing operator behaves?