为什么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)
将导致真正的当从引用转换E
到T
存在,但随后笔者通过明确排除的情况下继续当E
是null
字符或具有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
将返回true
当null
将被传递中,你将能够用做null
的文字? 没有 - 它是null
。 除了令人困惑的事情之外,它的true
意义是什么?
无论如何 - 就直觉而言,阅读英文代码并告诉我:
null is string;
当我看到这个问题时,它似乎在问这个问题is "nothing" a string?
。 我的直觉告诉我,不,它不是 - nothing
。
我认为null is string
返回false是非常直观的。 空无意义,绝对不是一个字符串。 所以它应该返回false。 虽然这是语言设计师所做的选择,但当您考虑null的真实世界含义时,这是非常直观的选择。
上一篇: Why does the is operator return false when given null?
下一篇: How the right associative of null coalescing operator behaves?