NullReferenceException on value type - c#

In my code I have a variable of type int. Directly after initalizing it, I receive a NullReferenceException. I am stumped why this is happening and actually how that is even possible.
Here is the code:
int lookupValue = 0;
if (0 == lookupValue)
And here is the debugger screen. The value of lookupValue is actually 0.

The debugger is showing the wrong line as the exception source. This does happen sometimes, you need to keep an eye on the surrounding code, and the stack trace.
Since you're working with a web application, it's also quite possible that the debugging information is out of sync with the code. Rebuilding the whole project might help, unless your dependencies are badly arranged.
Look at code ahead of the comparison, and below it as well (Is Session null? Is Session.UserId null? Is SqlCommands.LookupInsertCommand throwing NullReferenceException?). You can use quick watch to check pieces of code and find the one causing the NullReferenceException.
As a side-note, try not to carry practices from other languages to C#. Initialize local variables when you actually have a reasonable value to initialize them with - don't worry, the compiler will not allow you to compile code reading a variable that hasn't been assigned yet. When you just assign a default value, you're losing out on a few sanity checks of the code. Also, don't compare constant == variable. There's no reason to do that in C#, because you can't just accidentally type variable = constant - it will not compile (the only exception being the bool type, but you shouldn't compare that to a constant anyway - just do if (boolValue) or if (!boolValue)). It just makes the code harder to read and understand.
EDIT:
This case in particular is actually quite obvious if you know what you're looking for. You see, the if (0 == lookupValue) doesn't exist anywhere in the compiled binary - the compiler can safely ignore it, because lookupValue will always be 0. Usually, the debugging information will account for this, but missing by one line is quite common even when there's nothing as drastic as a whole missing line of code (in your case, likely more than one).
Since you are working with an ASP.NET application, part of the code isn't actually compiled by Visual Studio - it's compiled when you make a request. To generate proper debug information, you must also set the <compilation debug="true" /> in web.config (Compilation element).

There is no error in your code. anyway try this...
if (lookupValue.CompareTo(0) == 0)

Related

C# Comparing Values from dynamic's

Today i tried an old project, in my company and got an error which makes me curious. The issue line looks something like this:
if((dynamic)com_list.GetIntValue() != (dynamic)container.GetEnumValue())
The exception shows clearly that you can't compare Int32 with an Enum.
But i wonder, could this have ever worked, in some circumstance?
Are there changes in the dynamic Keyword which don't allow this anymore?
BTW, he also build this in the code like this:
if((dynamic)com_list.GetIntValue() != (dynamic)container.GetBooleanValue())
I'm still confused, why somebody would put this kind of comparing into productiv code.
No. The dynamic specification hasn't changed and I am pretty sure the evaluation in the compiler of such a trivial comparison didn't change overnight in one release to another. Most likely that code never worked.
Without additional cast from enum to int (or the other way around) it won't work.

Why does the debugger's breakpoint condition allow an assignment-statement as bool-condition?

This is very dangerous so I wonder why it's allowed. Since I often need to switch between VB.NET and C# I sometimes add breakpoint-conditions like following:
foo = "bah"
I want to stop if the string variable foo is "bah, so the correct way was to use foo == "bah" instead of foo = "bah".
But it "works". You don't get any warnings or errors at compile- or runtime. But actually this modifies the variable foo, it makes it always "bah" even if it had a different value. Since that happens silently (the breakpoint never gets hit) it is incredibly dangerous.
Why is it allowed? Where is my error in reasoning (apart from confusing the C# and VB.NET syntax)? In C# (as opposed to VB.NET) an assignment statement returns the value that was assigned, so not a bool, but a string in this case. But a breakpoint condition has to be a bool if you check the box "Is True".
Here is a little sample "program" and screenshots from my (german) IDE:
static void Main()
{
string foo = "foo";
// breakpoint with assignment(foo = "bah") instead of comparison(foo == "bah"):
Console.WriteLine(foo); // bah, variable is changed from the breakpoint window
}
The breakpoint-condition dialog:
The code as image including the breakpoint:
It is an automatic consequence of C# syntax, common in the curly-braces language group. An assignment is also an expression, its result is the value of the right-hand side operand. The debugger does not object either to expressions having side-effects, nor would it be simple at all to suppress them. It could be blamed for not checking that the expression has a bool result, the debugger however does not have a full-blown C# language parser. This might well be fixed in VS2015 thanks to the Roslyn project. [Note: see addendum at the bottom].
Also the core reason that the curly-brace languages need a separate operator for equality, == vs =. Which in itself must be responsible for a billion dollar worth of bugs, every C programmer makes that mistake at least once.
VB.NET is different, assignment is a statement and the = token is valid for both assignment and comparison. You can tell from the debugger, it picks the equality operator instead and doesn't modify the variable.
Do keep in mind that this is actually useful. It lets you temporarily work around a bug, forcing the variable value and allowing you to continue debugging and focus on another problem. Or create a test condition. That's pretty useful. In a previous life-time, I wrote a compiler and debugger and implemented "trace points". Discovered the same scenario by accident and left it in place. It ran in a host that relied heavily on state machines, overriding the state variable while debugging was incredibly useful. The accident, no, not so useful :)
A note about what other SO users are observing, it depends on the debugging engine that you use. The relevant option in VS2013 is Tools + Options, Debugging, General, "Use Managed Compatibility Mode" checkbox. Same option exists in VS2012, it had a slightly different name (don't remember). When ticked you get an older debugging engine, one that is still compatible with C++/CLI. Same one as used in VS2010.
So that's a workaround for VS2013, untick the option to get the debugger to check that the expression produces a bool result. You get some more goodies with that new debugging engine, like seeing method return values and Edit+Continue support for 64-bit processes.
I can disagree about buggy nature of this behavior. Few examples where for debugging purposes in my life if was useful:
1. Other thread modifies something in your code.
2. Other service updated value in db
So I suppose for cases of synchronization it can be useful feature, but I agree that it can cause problems
In Visual Studio 2019, variable assignment expressions in Breakpoint conditions no longer work.
The expression will be evaluated for value, but side effects such as variable assignment are discarded.
https://developercommunity.visualstudio.com/content/problem/715716/variables-cannot-be-assigned-in-breakpoint-conditi.html

Different property values on two references to the same object (C#)

I am trying to track down a very elusive bug in an application that manipulates a FlowDocument. I have shown below three consecutive lines of debugging code, together with their output:
Debug.Assert(ReferenceEquals(document1, document2));
Debug.WriteLine(document1.Blocks.Count); // 1
Debug.WriteLine(document2.Blocks.Count); // 3
Can anyone help me to understand how two references to the same object can have different values for a given property? Or am I missing something about the way ReferenceEquals works?
Thanks,
Tim
Edit:
If I change the assertion to an if block, the debugging code never runs ...
if (ReferenceEquals(document1, document2))
{
Debug.WriteLine(document1.Blocks.Count);
Debug.WriteLine(document2.Blocks.Count);
}
... which makes me feel utterly stupid, because the ReferenceEquals test is clearly working, but I don't understand why the assertion is not working.
Two things that might be happening from the top of my mind:
Accessing Blocks or Blocks.Count might mutate state (it shouldn't, but it is possible).
The object might be changed on another thread between the two calls. Do you use multi-threading in the application ?
Also, if the references are of different types (ie. document2 is of an inherited type), the property might be overloaded to return something different. You could check to see whether document1.GetType() == document2.GetType().
Edit in response to your update
Debug.Assert will only ever run, if the assembly is compiled in Debug mode. If you are running Release, it will not be run. This is because Debug.Assert is decorated with the [Conditional("DEBUG")] attribute.
It seems that the issue is the fact that you indeed have 2 different objects.
If a property has side effects it can yield different results each time you call it. E.g. DateTime.Now does not always equal DateTime.Now.
Without knowing anything more about the code, that would be my guess.
EDIT: Using Reflector on FlowDocument shows that Blocks return a new instance each time it is called. Additionally, the Count property BlockCollection is rather elaborate, so I would take a closer look at that. Unfortunately I don't know the involved types very well, so I can't immediately tell you what is wrong.
Possibilities (some of which you have already discounted in the comments):
Some external process, say something that is loading Blocks into FlowDocument, is altering the value between writes.
Heisenberg: reading the Blocks property affects it. This happens sometimes when reading rows from a data source. I'm not familiar with FlowDocument so I'm not sure how feasible this is.
If the instances were declared as different types, their references would still be equal, but the value of Blocks (or Blocks.Count) could be overridden, resulting in different return values since different code might be called - like Object.ToString() vs Int.ToString().
You're somehow calling this debug code in the middle of a loop. This could happen if you're running it in the command window or some attached debugger instead of within the application.
You have dead pixels on your screen that make the first "3" look like a "1".
You live next to a nuclear reactor.
Some things to try:
Run your .Assert code in a loop and see if the values stabilize.
Set a read/write breakpoint on the Blocks value. (I know you can do this in C, but haven't tried it in C#)
Update
Regarding your additional question about .Assert() not working as expected:
Just looked at this note on MSDN regarding Debug.Assert().
By default, the Debug.Assert method works only in debug builds. Use the Trace.Assert method if you want to do assertions in release builds. For more information, see Assertions in Managed Code.
Are you running a debug build or a release build?
Are you certain that the Blocks object reference points to the same object? Try a
Debug.Assert(ReferenceEquals(document1.Blocks, document2.Blocks));
and see if that succeeds.

C# Compiler should give warning but doesn't?

Someone on my team tried fixing a 'variable not used' warning in an empty catch clause.
try { ... } catch (Exception ex) { }
-> gives a warning about ex not being used. So far, so good.
The fix was something like this:
try { ... } catch (Exception ex) { string s = ex.Message; }
Seeing this, I thought "Just great, so now the compiler will complain about s not being used."
But it doesn't! There are no warnings on that piece of code and I can't figure out why. Any ideas?
PS. I know catch-all clauses that mute exceptions are a bad thing, but that's a different topic. I also know the initial warning is better removed by doing something like this, that's not the point either.
try { ... } catch (Exception) { }
or
try { ... } catch { }
In this case the compiler detects that s is written but not read, and deliberately suppresses the warning.
The reason is because C# is a garbage-collected language, believe it or not.
How do you figure that?
Well, consider the following.
You have a program which calls a method DoIt() that returns a string. You do not have the source code for DoIt(), but you wish to examine in the debugger what its return value is.
Now in your particular case you are using DoIt() for its side effects, not its return value. So you say
DoIt(); // discard the return value
Now you're debugging your program and you go to look at the return value of DoIt() and it's not there because by the time the debugger breaks after the call to DoIt(), the garbage collector might have already cleaned up the unused string.
And in fact the managed debugger has no facility for "look at the thing returned by the previous method call". The unmanaged C++ debugger has that feature because it can look at the EAX register where the discarded return value is still sitting, but you have no guarantee in managed code that the returned value is still alive if it was discarded.
Now, one might argue that this is a useful feature and that the debugger team should add a feature whereby returned values are kept alive if there's a debugger breakpoint immediately following a method execution. That would be a nice feature, but I'm the wrong person to ask for it; go ask the debugger team.
What is the poor C# developer to do? Make a local variable, store the result in the local variable, and then examine the local in the debugger. The debugger does ensure that locals are not garbage collected aggressively.
So you do that and then the compiler gives you a warning that you've got a local that is only written to and never read because the thing doing the reading is not part of the program, it's the developer sitting there watching the debugger. That is a very irritating user experience! Therefore we detect the situation where a non-constant value is being assigned to a local variable or field that is never read, and suppress that warning. If you change up your code so that instead it says string s = "hello"; then you'll start getting the warning because the compiler reasons, well, this can't possibly be someone working around the limitations of the debugger because the value is right there where it can be read by the developer already without the debugger.
That explains that one. There are numerous other cases where we suppress warnings about variables that are never read from; a detailed exegisis of all the compiler's policies for when we report warnings and when we do not would take me quite some time to write up, so I think I will leave it at that.
The variable s is used... to hold a reference to ex.Message. If you had just string s; you would get the warning.
I think the person that answers this will need some insight into how the compiler works. However, something like FxCop would probably catch this.
Properties are just methods, and there's nothing stopping anyone from putting some code that does something in the ex.Message property. Therefore, while you may not be doing anything with s, calling ex.Message COULD potentially have value....
It's not really the job of a compiler to work out every single instance and corner case when a variable may or may not be used. Some are easy to spot, some are more problematic. Erring on the side of caution is the sensible thing to do (especially when warnings can be set to be treated as errors - imagine if software didn't compile just because the compiler thought you weren't using something you were). Microsoft Compiler team specifically say:
"...our guidance for customers who are
interested in discovering unused
elements in their code is to use
FxCop. It can discover unused fields
and much more interesting data about
your code."
-Ed Maurer, Development Lead, Managed Compiler Platform
Resharper would catch that
Static analysis is somewhat limited in what it can accomplish today. (Although as Eric pointed out not because it doesn't know in this case.)
The new Code Contracts in .NET 4 enhances static checking considerably and one day I'm sure you'll get more help with obvious bugs like this.
If you've tried Code Contracts you'll know however that doing an exhaustive static analysis of your code is not easy - it can thrash for minutes after each compile. Will static analysis ever be able to find every problem like this at compile time? Probably not: see http://en.wikipedia.org/wiki/Halting_problem.

Why doesn't the C# compiler stop properties from referring to themselves?

If I do this I get a System.StackOverflowException:
private string abc = "";
public string Abc
{
get
{
return Abc; // Note the mistaken capitalization
}
}
I understand why -- the property is referencing itself, leading to an infinite loop. (See previous questions here and here).
What I'm wondering (and what I didn't see answered in those previous questions) is why doesn't the C# compiler catch this mistake? It checks for some other kinds of circular reference (classes inheriting from themselves, etc.), right? Is it just that this mistake wasn't common enough to be worth checking for? Or is there some situation I'm not thinking of, when you'd want a property to actually reference itself in this way?
You can see the "official" reason in the last comment here.
Posted by Microsoft on 14/11/2008 at
19:52
Thanks for the suggestion for
Visual Studio!
You are right that we could easily
detect property recursion, but we
can't guarantee that there is nothing
useful being accomplished by the
recursion. The body of the property
could set other fields on your object
which change the behavior of the next
recursion, could change its behavior
based on user input from the console,
or could even behave differently based
on random values. In these cases, a
self-recursive property could indeed
terminate the recursion, but we have
no way to determine if that's the case
at compile-time (without solving the
halting problem!).
For the reasons above (and the
breaking change it would take to
disallow this), we wouldn't be able to
prohibit self-recursive properties.
Alex Turner
Program Manager
Visual C# Compiler
Another point in addition to Alex's explanation is that we try to give warnings for code which does something that you probably didn't intend, such that you could accidentally ship with the bug.
In this particular case, how much time would the warning actually save you? A single test run. You'll find this bug the moment you test the code, because it always immediately crashes and dies horribly. The warning wouldn't actually buy you much of a benefit here. The likelihood that there is some subtle bug in a recursive property evaluation is low.
By contrast, we do give a warning if you do something like this:
int customerId;
...
this.customerId= this.customerId;
There's no horrible crash-and-die, and the code is valid code; it assigns a value to a field. But since this is nonsensical code, you probably didn't mean to do it. Since it's not going to die horribly, we give a warning that there's something here that you probably didn't intend and might not otherwise discover via a crash.
Property referring to itself does not always lead to infinite recursion and stack overflow. For example, this works fine:
int count = 0;
public string Abc
{
count++;
if (count < 1) return Abc;
return "Foo";
}
Above is a dummy example, but I'm sure one could come up with useful recursive code that is similar. Compiler cannot determine if infinite recursion will happen (halting problem).
Generating a warning in the simple case would be helpful.
They probably considered it would unnecessary complicate the compiler without any real gain.
You will discover this typo easily the first time you call this property.
First of all, you'll get a warning for unused variable abc.
Second, there is nothing bad in teh recursion, provided that it's not endless recursion. For example, the code might adjust some inner variables and than call the same getter recursively. There is however for the compiler no easy way at all to prove that some recursion is endless or not (the task is at least NP). The compiler could catch some easy cases, but then the consumers would be surprised that the more complicated cases get through the compiler's checks.
The other cases cases that it checks for (except recursive constructor) are invalid IL.
In addition, all of those cases, even recursive constructors) are guarenteed to fail.
However, it is possible, albeit unlikely, to intentionally create a useful recursive property (using if statements).

Categories

Resources