0

I am a relative newbie to C# as most of my web development work has been in VB. In VB something like a DataRow Object or Session Object will implicitly cast to say a string. I can say:

If myDataRow("name") = "Fred" Then  ...

I appreciate that in C# this casting must be explicit, so my question - all three of the lines below compile and work as expected. The ToString() will throw an exception if the session object is null so I guess that option is less 'good' as I would have to check for null first, but is one option more efficient or considered better C# coding practice than the others? Thanks a lot.

if ((string)Session["test"] == "abc") ...
if (Session["test"] as string == "abc") ...
if (Session["test"].ToString() == "abc") ...
Jon.A
  • 13
  • 7
  • 1
    I would try to refrain from asking "which is better" as this is highly subject to someone's opinion and then your question might be closed as "Primarily based on opinion". – Lasse V. Karlsen Jul 26 '21 at 06:54
  • As for my own opinion, if you know the value inside is always supposed to be a string, use the first one, the cast. This, however, will throw an InvalidCastException if at some point it's *not* a string (or `null`), so if it's supposed to be a string but for errors it might be something else then use `as string` as it will only return a string if what is inside *is* a string. Finally, if you want to compare it to a string regardless of type, and you want to just convert whatever into a string, use the last one though I would recommend using `?.ToString()` to automatically handle `null` values – Lasse V. Karlsen Jul 26 '21 at 06:56
  • 4
    I'd suggest `if (Session["test"] is string test && test == "abc")`. – Enigmativity Jul 26 '21 at 06:58
  • @Enigmativity That *would* be handled by the `as string` variant, though it might not be as clear to someone not experienced in reading C# code nuances. – Lasse V. Karlsen Jul 26 '21 at 06:59
  • @LasseV.Karlsen If that's a concern, I'd suggest making a function with a "self-documenting" name, that does the same. – Fildor Jul 26 '21 at 07:02
  • 1
    You're forgetting the most concise form, `if ("abc".Equals(Session["test"]))`, which does exactly what most people want, but nobody uses it, because it's weird. – John Wu Jul 26 '21 at 07:26

2 Answers2

1

There are many good responses to this here: Direct casting vs 'as' operator?

In short, the first option i.e. (string)Session["test"] == "abc" will throw a InvalidCastException if Session["test"] is not a string. Use this if you might want to throw an error on invalid cast.

The second option Session["test"] as string == "abc" will return null if the object which is typecasted is not a string. This option requires an explicit null check to be done post conversion before actually using the result.

If you definitely know that the object which you are typecasting is a string, you can use the first one and if in case it fails, you will definitely know that the cast failed and is easier to debug. If you are not sure of whether the object is a string, you might want to go for the second option.

Nikhil Mehta
  • 355
  • 2
  • 7
  • In this case, the second option does not need an additional null check, because the implicitly called `operator==(string, string)` will correctly handle comparing a string with null. – PMF Jul 28 '21 at 05:51
  • @PMF yes that line was a little ambiguous. What I meant was it's better to have a null check before using the resultant string value i.e. calling any string methods on the result. If it is not done, a NullReferenceException might occur. I have edited the answer to make it a bit more clearer – Nikhil Mehta Jul 28 '21 at 05:57
0

As already pointed out in the comments above, there's a fourth possibility, which works with recent compiler versions:

if (Session["test"] is string test && test == "abc")
{
    // will get here only if the field was not null and is "abc"
}

The is operator returns false if the object is null, but if it is not null and the type matches, the value is assigned to the variable.

PMF
  • 14,535
  • 3
  • 23
  • 49