简体   繁体   English

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

[英]Why does the is operator return false when given null?

It seems to me that the is operator is a bit inconsistent. 在我看来, is运算符有点不一致。

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

One expects that the null value belongs to any reference (or nullable) type. 一个人期望null值属于任何引用(或可空)类型。 And indeed, the C# language specification says something which supports this hypothesis, for example (6.1.6 Implicit reference conversions): 事实上,C#语言规范说明了支持这种假设的东西,例如(6.1.6隐式引用转换):

The implicit reference conversions are: 隐式引用转换是:
... ...
• From the null literal to any reference-type. •从null文字到任何引用类型。

The description (7.10.10 The is operator) of the is operator starts by saying that the expression (E is T) will result in true when a reference conversion from E to T exists, but then the authors go on by explicitly excluding the case when E is the null literal or has a null value. 说明(7.10.10 is运算符)的is通过说表达式运算符开始(E is T)将导致真正的当从引用转换ET存在,但随后笔者通过明确排除的情况下继续当Enull文字或具有null值时。

Why do they do that? 他们为什么这样做? To me it seems counterintuitive. 这对我来说似乎违反直觉。

This question was the subject of my blog on May 30th 2013 . 这个问题是我2013年5月30日博客主题 Thanks for the great question! 谢谢你这个好问题!


You're staring at an empty driveway. 你正盯着一条空车道。

Someone asks you "can your driveway hold a Honda Civic?" 有人问你“你的车道可以装一辆本田思域吗?”

Yes. 是。 Yes it can. 是的,它可以。

Someone points you at a second driveway. 有人指着你在第二个车道。 It is also empty. 它也是空的。 They ask "Can the current contents of my driveway fit in your driveway?" 他们问:“我的车道的当前内容能否适合您的车道?”

Yes, obviously. 是的,很明显。 Both driveways are empty! 两条车道都是空的! So clearly the contents of one can fit in the other, because there are no contents of either in the first place. 很明显,一个人的内容可以适合另一个,因为首先没有任何内容。

Someone asks you "Does your driveway contain a Honda Civic?" 有人问你“你的车道是否包含一辆本田思域?”

No, it does not. 不,不是的。

You're thinking that the is operator answers the second question: given this value, does it fit in a variable of that type? 您认为is运算符回答了第二个问题: 给定此值,它是否适合该类型的变量? Does a null reference fit into a variable of this type? null引用是否适合此类型的变量? Yes it does. 是的,它确实。

That is not the question that the is operator answers. 这不是问题的is运营商的答案。 The question that the is operator answers is the third question. 现在的问题是, is运营商的答案是第三个问题。 y is X does not ask " is y a legal value of a variable of type X ? " It asks " Is y a valid reference to an object of type X ? " Since a null reference is not a valid reference to any object of any type, the answer is "no". y is X不问“ y类型的变量的合法值X ?”这问“ y至类型的对象的有效引用X ?”由于空引用不是任何 任何对象的有效引用类型,答案是“不”。 That driveway is empty; 那条车道是空的; it doesn't contain a Honda Civic. 它不包含本田思域。

Another way to look at it is that y is X answers the question "if I said y as X , would I get a non-null result? If y is null, clearly the answer is no! 另一种看待它的方法是y is X回答问题“如果我说y as X ,我会得到非空结果吗?如果y为空,显然答案是否定的!


To look a little deeper at your question: 要更深入地了解您的问题:

One expects that the null value belongs to any reference (or nullable) type 一个人期望null值属于任何引用(或可空)类型

One would be implicitly assuming that a type is a set of values , and that assignment compatibility of a value y with a variable of type X is nothing more nor less than checking whether y is a member of set x . 可以隐含地假设类型是一组值 ,并且值y与类型X的变量的赋值兼容性仅仅是检查y是否是集合x的成员

Though that is an extremely common way of looking at types, that is not the only way of looking at types, and it is not the way that C# looks at types. 虽然这是查看类型的一种非常常见的方式,但这不是查看类型的唯一方法,而且它不是C#查看类型的方式。 Null references are members of no type in C#; 空引用是C#中没有类型的成员; assignment compatibility is not merely checking a set to see if it contains a value. 分配兼容性 不仅仅检查组,看它是否包含一个值。 Just because a null reference is assignment compatible with a variable of reference type X does not mean that null is a member of type X. The "is assignment compatible with" relation and the "is a member of type" relation obviously have a lot of overlap, but they are not identical in the CLR. 仅仅因为null引用是赋值与引用类型X的变量兼容并不意味着null是X类型的成员。“赋值与”关系兼容并且“是类型的成员”关系显然有很多重叠,但它们在CLR中不相同。

If musings about type theory interest you, check out my recent articles on the subject: 如果关于类型理论的思考对你感兴趣,请查看我最近关于这个主题的文章:

What is this thing you call a "type"? 你称之为“类型”的东西是什么? Part one 第一部分

What is this thing you call a "type"? 你称之为“类型”的东西是什么? Part Two 第二部分

The null literal can be assigned to any reference type. 可以将null文本分配给任何引用类型。 It is not a type in an of itself. 它本身并不是一种类型。 It is a special literal that represents a null reference. 它是一个特殊的文字表示空引用。

In the case that is would return true when a null would be passed in, what would you be able to do with the null literal? 在这种情况下is将返回truenull将被传递中,你将能够用做null的文字? Nothing - it is null . 没什么 - 它是null What would be the point of it returning true except for confusing matters? 除了令人困惑的事情之外,它会回归true的重点是什么?


Regardless - in terms of how intuitive that is, read the code in English and tell me: 无论如何 - 就直观性而言,请阅读英文代码并告诉我:

null is string;

When I see that, it seems to be asking the question is "nothing" a string? 当我看到它时,它似乎在问这个问题is "nothing" a string? . My intuition tells me that no, it isn't - it's nothing . 我的直觉告诉我,不,它不是 - 它nothing

I think null is string returning false is very intuitive. 我认为null is string返回false是非常直观的。 Null means nothing, and it is definitely not a string. Null意味着什么,它绝对不是一个字符串。 So it should return false. 所以它应该返回false。 While it is a choice the language designers made, it is a very intuitive one when you consider the real world meaning of null. 虽然它是语言设计者的选择,但当你考虑null的真实世界意义时,它是一个非常直观的选择。

http://msdn.microsoft.com/en-us/library/scekt9xw%28v=vs.71%29.aspx http://msdn.microsoft.com/en-us/library/scekt9xw%28v=vs.71%29.aspx

An is expression evaluates to true if both of the following conditions are met: 如果满足以下两个条件,则表达式的计算结果为true:

  • expression is not null. 表达式不为空。
  • expression can be cast to type. 表达式可以转换为类型。 That is, a cast expression of the form (type (expression) will complete without throwing an exception. For more information, see 7.6.6 Cast expressions. 也就是说,表单的类型(表达式)将在不抛出异常的情况下完成。有关更多信息,请参阅7.6.6 Cast表达式。

As a practical matter, having "null is T == false" saves me typing extra code: 实际上,“null是T == false”可以节省我输入额外的代码:

Instead of having to say 而不是说

if (X != null && X is Foo) {}

I can just say 我可以说

if (X is Foo) {}

and be done with it. 并完成它。

the null value null

I've quoted this from your question because it seems to get to the heart of the matter. 我从你的问题中引用了这个,因为它似乎触及了问题的核心。 null isn't a value - it's the absence of a value. null 不是值 - 它是缺少值。 The purpose of is to me seems to be to answer the question: 的目的is对我似乎是回答这个问题:

If I cast E to T , will I successfully get a T ? 如果我把E投到T ,我会成功获得T吗?

Now, while you can cast null to T without error , after doing so you don't "have a T " - you've still got nothing. 现在,虽然你可以毫无错误地将nullT 这样做之后你就不会 “有一个T ” - 你仍然没有任何东西。 So it's not the case that null "is" a T , so is returns false. 所以它不是的情况下null “是” T ,所以is返回false。

In Java there is an operator that does exactly same thing, but it has much longer name: instanceof . 在Java中,有一个运算符执行完全相同的操作,但它具有更长的名称: instanceof It's very intuitive there that null instanceof String returns false, because null is not an instance of anything, much less a String . 在那里, null instanceof String返回false是非常直观的,因为null不是任何东西的实例,更不是String So, when using null the Java's version is bit more intuitive. 因此,当使用null ,Java的版本更直观一些。

However, both of those operators return true when asked to look through entire hierarchy as well. 但是,当要求查看整个层次结构时,这两个运算符都返回true。 Eg. 例如。 if instance of String is an Object . 如果String实例是Object And here it's Java that's bit less intuitive (because an instance actually has one, very specific type) and C#'s is is more intuitive (because every String is an Object deep inside). 这里,它的Java这是不太直观的(因为一个实例实际上有一个非常特殊类型)和C#的is更直观的(因为每一个String 一个Object内心深处)。

Bottom line: if you try to describe pretty advanced logic in one word, you're bound to have few people confused, this way or another. 一句话:如果你试图用一个词来描述非常高级的逻辑,那么你很少会有这样或那样的人混淆。 It seems that most people agreed on one meaning and those who did not agree, had to adjust. 似乎大多数人都同意一个意思而那些不同意的人不得不进行调整。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如果为空,空条件运算符是否返回假? - Does null conditional operator return false if null? 当= =为空值返回true时,为什么> =返回false? - Why does >= return false when == returns true for null values? 为什么IS运算符在false时输入IF语句? - why does the IS operator enters an IF statement when false? 为什么接口返回 null 而不是 true/false - why does interface return null instead of true/false 为什么当第一个操作数为假时,重载的 '&amp;' 运算符不会触发? - Why overloaded '&' operator does not triggering when the first operand is false? 为什么C#Null条件运算符不返回Nullable <T> ? - Why C# Null Conditional operator does not return Nullable<T>? 为什么当返回值不是 null 时,此服务返回 null? - Why does this service return null when return value is not null? 为什么当用简写形式表示时,此三元语句会返回假肯定? - Why does this ternary statement return false positives when in shorthand notation? 为什么IsGenericTypeDefinition返回false? - Why does IsGenericTypeDefinition return false? 为什么这个IF语句返回false? - Why does this IF statement return false?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM