14

I'm having a weird behaviour trying to get the value of a boolean property stored at HttpContext.Current.Session.

The object is a boolean. First I'm trying to check if the object exists and, if exists, use it.

I'm trying to use it in a ?: operator but it behaves strange. Here is my Watch window: Watchers from VisualStudio

Premise

  • The "ExistingKey" key exists and has a value of false (if key doesn't exists returns false).

Results

  1. When checking if !=null it returns false (first thing weird).
  2. When using the ?: operator, besides the condition is false, it returns the first expression, 4 (second thing weird).

Could somebody explain this behaviour?


Note: I'm not asking for an alternative to bypass this situation. Just asking why this works like this.

Gilad Green
  • 36,708
  • 7
  • 61
  • 95
Mario Levrero
  • 3,345
  • 4
  • 26
  • 57
  • 1
    Well, I tested it and `HttpContext.Current.Session["ExistingKey"] != null` actually returns true. I'm also curious about this behavior. – uTeisT Aug 26 '16 at 09:16
  • It looks correct to me. ExistingKey has a value; it isn't null. And all of your comparisons reflect that. So what is the issue? – Jeff Siver Aug 26 '16 at 13:52
  • 1
    @JeffSiver `HttpContext.Current.Session["ExistingKey"] != null` returns false but it should be true instead. In my test, it was true as well btw. I suspect it's something related with the current context but just can't confirm. Maybe someone who experienced the issue before can help – uTeisT Aug 27 '16 at 19:57
  • 1
    @uteist, I'm confused with your watch window. The last two items, with the ? 4 : 5 are correct. Is there a typo in the third item that is making it display differently? – Jeff Siver Aug 28 '16 at 19:18
  • It's not my watch window, it's Mario's. I tested it myself as well, and probably you and I have same results. His, though, is different.. – uTeisT Aug 28 '16 at 19:37
  • 2
    @GiladGreen - Why is line 4 incorrect? The only one that doesn't fit is line 3. All the other ones are consistant. – ConnorsFan Aug 29 '16 at 00:33
  • Could there be an invisible character in line 3? Or a wrong character? Do you get the same result if you retype that line? – ConnorsFan Aug 29 '16 at 00:52
  • Yeah, line 4 is actually correct. It's just inconsistent with line 3 which, I believe, is the problematic one. – uTeisT Aug 29 '16 at 07:12
  • My understanding is : 1) Session["ExistingKey"] holds false so it is not null. At ITEM 4 when we say if it not null 4 is assigned to it . SO at Item 5 when we say == null , since Session["ExistingKey"] hold 4 now the condition is false and 5 gets assigned. – FakeisMe Sep 01 '16 at 08:19
  • Try and see if you can reproduce this problem in code instead of watch window. Watch window can produce false type comparison result especially when its an object – Steve Sep 02 '16 at 20:56
  • place a breakpoint in session[index] indexer and check if some one else is changing it. – SHM Sep 03 '16 at 12:48
  • Boolean seems to be a special beast, this does work though: bool test = Session["ExistingKey"] != null. It does work as expected with other value types. – Michel van Engelen Jan 03 '17 at 13:35
  • Added to my last comment, it does work with Session["ExitingKey"] = true. Maybe the disctinction between an object, in this case a non-nullable value type, with value false and null is a bridge too far for the runtime. – Michel van Engelen Jan 03 '17 at 13:53

2 Answers2

2

It seems to be some sort of bug within the watch window. I tested the following code:

protected void Page_Load(object sender, EventArgs e)
{
   var  objDict = new Dictionary<string, object>();
    var boolDict = new Dictionary<string, bool>();
    Session["ExistingValue"] = false;
    bool? nullableValue = false;

    Session["ExistingValueNullable"] = nullableValue;
    var existingValue = (bool)Session["ExistingValue"];
    var existingValueIsNotNull = Session["existingValue"] != null;
    objDict["ExistingValue"] = false;
    boolDict["ExistingValue"] = false;
    bool existingValueIsNotNullIf = false;
    if (Session["ExistingValue"] != null)
    {
        existingValueIsNotNullIf = true;
    }
}

And I got the following in the watch window:

Watch Window

So you can see that in the case of Session and a Dictionary<string,object> the != null evaluates to false. A Dictionary<string,bool> evaluates this comparison properly.

Weirdly, 'Session["ExistingValue"] != null' and 'Session["ExistingValue"]' == null' are both false.

If I cast the session value to a bool first then compare to null, I get the correct result.

Finally, if I test the value 'Session["ExistingValue"] != null' in code, I get a proper result. Which at least reassures me that this is something in the watch window, and there shouldn't be a similar issue in code.

All my testing was in Visual Studio 2015.

Hans Kesting
  • 38,117
  • 9
  • 79
  • 111
MikeS
  • 1,734
  • 1
  • 9
  • 13
1

Please do not consider this an answer at the moment, the following is much easier to write in an answer than in a comment due to space and formatting constraints.

I agree with the comments on the question, line 3 is not consistent with the results of the other lines. The only thing I can think of that could explain this is that the Watch window in Visual Studio has stale data / has a corrupted state. I think executing the same statements but in the code itself could prove or refute this. The following code is the same as what you have but output to a StringBuilder. Could you execute this and post the resulting string and let us know if this is any different from what you have in your Watch window?

var session = HttpContext.Current.Session;
var builder = new System.Text.StringBuilder();

builder.AppendFormat("session[\"someKeyThatDoesNotExist\"] => value {0}", session["someKeyThatDoesNotExist"] ?? "null").AppendLine();
builder.AppendFormat("session[\"ExistingKey\"] => value {0}", session["ExistingKey"] ?? "null").AppendLine();
builder.AppendFormat("session[\"ExistingKey\"] != null => value {0}", session["ExistingKey"] != null).AppendLine();
builder.AppendFormat("session[\"ExistingKey\"] != null ? 4 : 5 => value {0}", session["ExistingKey"] != null ? 4 : 5).AppendLine();
builder.AppendFormat("session[\"ExistingKey\"] == null ? 4 : 5 => value {0}", session["ExistingKey"] == null ? 4 : 5).AppendLine();

var totalDebugInfo = builder.ToString();
Igor
  • 60,821
  • 10
  • 100
  • 175