• Lars (unregistered)

    The preferred test on (not) null in C# is actually:

    if (someVariable is null)


    if (someVariable is object)

    Every comparison with == calls the operator of that class which may behave weird (it should not, but who knows...).

  • gp (unregistered)

    this doesn't actually work - the var pattern matching accepts nulls as well, so the if condition will always be true.

  • Guest (unregistered)

    If I'm not mistaken,


    is only called if someObjThatMayBeNull is null.

  • my name is missing (unregistered)

    Clever belongs in Daily WTF comments not your codebase.

  • Canthros (unregistered)

    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.

  • (nodebb)

    //object is null, react somehow

    No it isn't. It's not null when it gets here.

    By casting explicitly to object, we guarantee that our type is a reference type, so this makes sure that we don’t get weird behavior on value types, like integers.

    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.

  • Canthros (unregistered) in reply to chucker23n

    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

  • Anonymous') OR 1=1; DROP TABLE wtf; -- (unregistered)


    A pattern match with the var pattern always succeeds. Its syntax is:

    expr is var varname

    If expr evaluates to null, the is expression produces true and assigns null to varname. The var pattern is one of the few uses of is that produces true for a null value.

    What strange and surprising behavior. TIL!

  • TheJayMann (github)

    Came here just to state that the article is wrong. Others have pointed this out as well. Ran the following code in C# Interactive.

    > string a = null;
    > if (((object)a) is var _) {
    .     Console.WriteLine("A is null");
    . }
    . else {
    .     Console.WriteLine("A is not null");
    . }
    A is null
    > string a = "Test";
    > if (((object)a)is var _) {
    .     Console.WriteLine("A is null");
    . }
    . else {
    .     Console.WriteLine("A is not null");
    . }
    A is null
  • comment is var _ (unregistered)

    ((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.

  • Sole Purpose Of Visit (unregistered)

    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.

  • (nodebb)

    Maxim 43: If it's stupid and it works, it's still stupid and you're lucky.

  • Sole Purpose Of Visit (unregistered) in reply to TheJayMann


    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.

  • Sole Purpose Of Visit (unregistered) in reply to Sole Purpose Of Visit

    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.

  • Tim! (unregistered)

    I was surprised to learn that the (object) cast doesn't force the discard to be inferred as of type 'object'.

  • shcode (unregistered)

    "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.

  • TheJayMann (github) in reply to Sole Purpose Of Visit

    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.

  • (nodebb)

    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:

    if(someObjThatMayBeNull is null)

    Unfortunately, it doesn't behave properly for strings, so they get an "is probably null" test instead of an "is null" test.

  • i be guest (unregistered)

    But “NotAThingThatHappens” found approach:

    I found approach too. Is good approach.

  • 333fred (Compiler Dev) (unregistered)

    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===

  • Future (unregistered)

    So TRWTF is that the C# compiler doesn’t warn you about unreachable branches?

  • Mirality (unregistered)

    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.

Leave a comment on “A Variation on Nulls”

Log In or post as a guest

Replying to comment #516479:

« Return to Article