Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Comparing strings with != operator giving different results?

I know this might sound like a very stupid question but I'm out of answers on this one. One of our users reported a bug recently and I realized that an old bit of code was using != string.Empty rather that IsNullOrEmpty(). I fixed it with IsNullOrEmpty() and it now runs fine, but I'd like to actually understand the problem

The thing is, the exact same bit of code runs differently on certain machines. I basically have an object: context["MODE"], that is supposed to be empty. I added some tests on it to log:

        contextBuilder.AppendLine("MODE: |" + context["MODE"] + "|");
        contextBuilder.AppendLine("MODE != string.Empty: " + (context["MODE"] != string.Empty));
        contextBuilder.AppendLine("MODE TRIM != string.Empty: " + (context["MODE"].ToString().Trim() != string.Empty));
        contextBuilder.AppendLine("MODE.IsNullOrEmpty: " + string.IsNullOrEmpty(context["MODE"].ToString()));
        contextBuilder.AppendLine("MODE.TRIM.IsNullOrEmpty: " + string.IsNullOrEmpty(context["MODE"].ToString().Trim()));

Here are my logs about that field details:

MODE: || 
MODE != string.Empty: False  
MODE TRIM != string.Empty: False 
MODE.IsNullOrEmpty: True  
MODE.TRIM.IsNullOrEmpty: True

Here are his logs:

MODE: ||
MODE != string.Empty: True
MODE TRIM != string.Empty: False
MODE.IsNullOrEmpty: True
MODE.TRIM.IsNullOrEmpty: True

As you can see there is one difference: MODE != string.Empty is False for me (makes sense), True for him! MODE is obviously not null (otherwise .ToString() would have failed) The problem is fixed by using IsNullOrEmpty but I'm trying to figure out exactly why would this not work on certain user's machines and not others. Typically with my tests some of us had no problems, other had.

I don't really understand what can I learn about it. Why is his mode different than null and String.Empty, but IsNullOrEmpty returns true? Also note that the trim is actually string.Empty as well

Thank you!

like image 286
Damascus Avatar asked Sep 23 '22 03:09

Damascus


1 Answers

If you use ToString(), that's an indication that the type of context["MODE"] is object. If you compare an object with a string using !=, you're comparing string references, not the actual string values.

So "his mode" is an empty string that is not the same reference as string.Empty.

Don't use reference comparisons on strings; always ensure both sides are of type string before using == or !=.

Note that the C# compiler should have warned you about this: CS0252: Possible unintended reference comparison

like image 117
Daniel Avatar answered Oct 11 '22 13:10

Daniel