- Feature Articles
- CodeSOD
- Error'd
- Forums
-
Other Articles
- Random Article
- Other Series
- Alex's Soapbox
- Announcements
- Best of…
- Best of Email
- Best of the Sidebar
- Bring Your Own Code
- Coded Smorgasbord
- Mandatory Fun Day
- Off Topic
- Representative Line
- News Roundup
- Editor's Soapbox
- Software on the Rocks
- Souvenir Potpourri
- Sponsor Post
- Tales from the Interview
- The Daily WTF: Live
- Virtudyne
Admin
The preferred test on (not) null in C# is actually:
or
Every comparison with == calls the operator of that class which may behave weird (it should not, but who knows...).
Admin
this doesn't actually work - the var pattern matching accepts nulls as well, so the if condition will always be true.
Admin
If I'm not mistaken,
UseTheObjectInAMethod(someObjThatMayBeNull);
is only called if someObjThatMayBeNull is null.
Admin
Clever belongs in Daily WTF comments not your codebase.
Admin
The var pattern accepts nulls, and the resulting variable is not scoped to the if statement, because the scoping behavior with C#'s pattern matching is kind of arbitrary.
Admin
//object is null, react somehow
No it isn't. It's not null when it gets here.
I fail to see what use casting to object is here. A value type will never be null, so the expression will always be true. Casting to object doesn't change that.
Admin
It's potentially anything. The var pattern will match nulls, so the else isn't reachable.
Here's a demo in sharplab: https://sharplab.io/#v2:C4LgTgrgdgNAJiA1AHwAICYCMBYAUBgBjwwGYACAbzzJrIAcwBLANwENgBTM1TANm4AsZAGIB7UQB4AKgD4AFFLIBnUQFsOAeQBGAKykALdgFlWATwBCHAHIQANrYCUlarVeMAZnK+jdHAMbADirq2nqGwCYW1naOZIxKZGxgZAD6Di6uNFS4mblkAPT5Pjr+wHEJUDEwZGAcrAHKahz6ogDuGXk0PACccgAkAEQAOgDklfaj9Oz6NXV++hxw1RRQrOqinsGaugbGZpY29g4AvuWUW6G7EfvR9gD8AHRSogDKwExQAOZyTnd3ZAMJFYAKoAGVBMgGxwGDgA3B1XKcEbQOLYlBxkVkyJjaMD0QZtiUAgBJKAAQSMHGALTgcguO3CkQOMThOOOOJSZAAvGQ4Bx3Kw7MAFKycrR2WKaB0GCx2FwePwtOJbKlWqwlIdbPDJfQmGxONw+IIyHiOATQqVSRSqTTpPJFAAPJzZTo9frDMaiMrjWyTOjTWb1BZLSirdaeJ2neKUB2PZ5vD7fX7/QEg8GQ6GixEdDoYdDOHWuFJqjUxblkAVojjazo4sSiLwJxhfJw+rN5N3F9Wa9u5OviRvvZufJwDdziLSsMAwmsdzC9Lulo6zvuF2iLzXl94Qas4/sNuRNltkNsrzKdks9s+ufeDxOj8c+KcznEX7ss6+0V/zuQDQA8G4AIPsvjqErHEAA
Admin
https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/is#var-pattern
What strange and surprising behavior. TIL!
Admin
Came here just to state that the article is wrong. Others have pointed this out as well. Ran the following code in C# Interactive.
Admin
((object)a) is object
might work. But yeah this is dumb. I do have to wonder, given the above comments, whether TRWTF is anonymisation, because surely if you were writing this as throwaway testing code it would actually have to do the null check correctly.
Admin
The frightening thing to me is that pattern matching only arrived with C# 7 afaik.
Give somebody a more powerful discriminator, and they will still turn it it into WTF trash.
Admin
Maxim 43: If it's stupid and it works, it's still stupid and you're lucky.
Admin
Splendid.
Now, explain to us all why casting anything to an object C# makes any sense at all?
Either you want something that is derived from "object", in which case casting is nonsensical, or you want to test against null.
Here's an Occam's Razor to shave yourself with tomorrow.
Admin
Oh, and if you try casting a value type to a null -- the compiler will complain.
Which presumably relates to Canthros' point, above.
I'll repeat. Give somebody a better hammer, and they will whack themselves in the head wit it.
Admin
I was surprised to learn that the (object) cast doesn't force the discard to be inferred as of type 'object'.
Admin
"Normally, the _ is a discard."
... i didn't know such a thing exists. thank you, tdwtf, stuff like this is one of the reasons i visit and read you daily.
Admin
My reason for casting the value to object in the example was to mimic the code provided by the article as closely as possible. Given that C# has implicit upcasting, and that all values are of types deriving from object, a cast to object, as far as I can tell, is never necessary. The only real purpose it could serve would be to box a value type, but, even then, that boxing can wait until the the value type is being assigned to an object typed field or parameter. In fact, while typing the code in the interactive pane, the suggestions told me that the cast to object is redundant, as well as the set of parenthesis around the
a
variable is unnecessary. Also, as I expected, the _ is actually being used as a discard pattern, and not being created as a variable. This can be seen as, when trying to use the _ variable inside the if block (or, really, anywhere else) results in an error that the name does not exist in the current context. This ultimately tells me that, with the submission of the article, someone along the chain really doesn't understand C#, and also really did not completely test the submitted code. Perhaps they tested the case where the variable was null, saw the expected outcome, and assumed it worked without testing the case when not null.Ultimately, to answer the question, I can not find any good reason in C#, or in any language which has implicit upcast and implicit boxing, to cast to object. And, even in F#, where upcasting is explicit, it is better to use the box function.
Admin
They cast to object so that the implicitly typed _ variable picks up object as a data type. They're hoping that an implicitly typed object variable will be initialized as null and the code then reduces to:
Unfortunately, it doesn't behave properly for strings, so they get an "is probably null" test instead of an "is null" test.
Admin
I found approach too. Is good approach.
Admin
I hate to tell you this, but this is not a valid test for null.
var
patterns accept any input. They always return true, no matter what the input is. The false case here is unreachable code, though we don't warn you about it. You can see the output of running something like that here: https://sharplab.io/#v2:EYLgtghgzgLgpgJwDQxAgrgOwD4AEBMAjALABQBADGQQMwAEA3mXS3Qfo869wCpywAKTOgA2IgJQBuLtxZ9BmOAHc6Ae2AArOAGMYA8VJl0AvkaO56uQgDY2AFjry96rbrXijTUrNYBLAGZ0Aqp0vlB0AG4QCHQA+h7ePpyJSaxWAJwCAEQAYqqqWYYpsqbF3HAiUHBG3F6p3BnZAELRhdJlrKXcpcZAA===Admin
So TRWTF is that the C# compiler doesn’t warn you about unreachable branches?
Admin
Explicitly casting to object could be useful in generic methods where you're not sure whether the value is a reference or value type, so you want to force boxing on the latter. Having said that, it's rarely necessary in practice because the compiler allows you to use == null (or better, ReferenceEquals) on possibly-value-type generic arguments... although I think this may not have worked as well in some older compiler versions.
But yeah, as others have said, the entire premise of this article is flat out wrong, "is var" will always return true.