Can you capture the name of the object that throws a NullReferenceException? - c#

Is there a way to find out what specific object caused a NullReferenceException? I've read the page about troubleshooting NullReferenceExceptions and it talks about inspecting variables in the debugger and looking at the exception message.
What if the exception was thrown in production code so you can't run a debugger to inspect the variables? The exception message shows the stack trace so you can see what method the exception was thrown in, but it does not say which specific object was null.
I'd like to be able to add the name of the object that was null to the error message so that when I'm looking into reports from users and I come across a NullReferenceException, I can easily see what object was null and fix it. Does anyone know of a way to do this?
I also found this question which asked the same thing, but it was from 2011 and I don't know if anything has changed since then.
Edit: The question that this is flagged as a duplicate is indeed a duplicate but is also very old (2008). Has anything changed since then?
Edit 2: I found this when googling this question. Visual Studio can tell you what threw the NullReferenceException; is there any way to tap into this to add it to a log file?

It should be relatively easy to figure out given the stacktrace, but a better approach would be to include "validation" or parameters and/or null checks in your code and explicitly throw a ArgumentNullException yourself before you try to access a member of a variable that may not has been initialized. You can then supply the name of the uninitialized object:
if (obj == null)
throw new ArgumentNullException(nameof(obj));
It's a common practise to perform these checks on arguments in both constructors and methods, e.g:
public void SomeMethod(SomeType someArgument)
{
if (someArgument == null)
throw new ArgumentNullException(nameof(someArgument));
//you will never get there if someArgument is null...
var someThing = someArgument.SomeMember;
if (someThing == null)
throw new ArgumentException("SomeMember cannot be null.", nameof(someArgument));
...
}

TL;DR
The answer to your question is No, it's not possible.
The article speaks about the source code location and not the object. But much of the answer is covered in the article you shared, and if you read it fully you will know why it's not possible. For the benefit of everyone i will add the excerpt here.
Based on the available assembly metadata as of today, the runtime can infer the location of the problem and not the object.
There are no guarantees that the PDB is always there with required information to weave the IL back to a n identifier.
It's not just C#,but a bunch of other languages have to support this to make this work in the .NET runtime, which is less likely at this moment.
Assembly Metadata doesn't have debug information
Finding a name of an object during runtime requires debug information to be available, which is based on the configuration you used to build your code. There is no guarantee that the runtime can weave an address or register to a name. The assembly metadata contains the description of the Assembly , Data Types and members with their declarations and implementations, references to other types and members , Security permissions but doesn't contain source information.
Using PDB's would make it inconsistent as you don't have control over framework and library (nuget) code
I think it might not even be possible to do this consistently, Even if all compilers targeting CLR, emit enough information about identifiers (all language compilers) and the runtime consume it. The way the .NET project gets compiled won't be consistent given the fact that any .NET project that i can think of reference binaries from community / NuGet. In that case a part of the code report identifier names and the other part wouldn't.
Consider what happens to the generated types (for example IEnumerable) The runtime can figure out and report that IEnumerable.Current is null, but what is null is the underlying object in the container, which still doesn't give the answer. You walk the stack and figure out the underlying object and fix it, which is the case even without the information.
Consider multithreaded code, where you might know which object is null, but you might not know which context / call stack caused it to be null.
So my conclusion is,
we should try to infer context from methods than identifiers. Identifiers tell you what is null, but often you need to figure out why it is null because the programmer didn't anticipate it, he has to walk the stack back to figure out the issue. In case where the object is a local variable it's a programmer's error and might not have to be the runtime to figure it out.

Whenever an Exception is thrown, AppDomain.CurrentDomain.FirstChanceException is raised. You can add a handler to this event, to monitor how many exceptions are thrown, and from where during runtime. In the event handler, you have access to the actual Exception object. If a particular type of exception is of interest, you simply check the type of the Exception property on the event arguments object passed to the handler.
The following example outputs all exceptions (including inner exceptions) to a text file, including stack traces, for analysis later. Since exceptions are often caught and re-thrown, the same exception might occur multiple times in the output file, with longer and longer stack traces. Using such a file allows you to find the source of particular types of exceptions. You can also get frequency and occurrence, and other types of information from such a file.
AppDomain.CurrentDomain.FirstChanceException += (sender, e) =>
{
if (exceptionFile is null)
return;
lock (exceptionFile)
{
if (!exportExceptions || e.Exception.StackTrace.Contains("FirstChanceExceptionEventArgs"))
return;
exceptionFile.WriteLine(new string('-', 80));
exceptionFile.Write("Type: ");
if (e.Exception != null)
exceptionFile.WriteLine(e.Exception.GetType().FullName);
else
exceptionFile.WriteLine("null");
exceptionFile.Write("Time: ");
exceptionFile.WriteLine(DateTime.Now.ToString());
if (e.Exception != null)
{
LinkedList<Exception> Exceptions = new LinkedList<Exception>();
Exceptions.AddLast(e.Exception);
while (Exceptions.First != null)
{
Exception ex = Exceptions.First.Value;
Exceptions.RemoveFirst();
exceptionFile.WriteLine();
exceptionFile.WriteLine(ex.Message);
exceptionFile.WriteLine();
exceptionFile.WriteLine(ex.StackTrace);
exceptionFile.WriteLine();
if (ex is AggregateException ex2)
{
foreach (Exception ex3 in ex2.InnerExceptions)
Exceptions.AddLast(ex3);
}
else if (ex.InnerException != null)
Exceptions.AddLast(ex.InnerException);
}
}
exceptionFile.Flush();
}
};
(Example from the IoT Gateway project on GitHub, with permission).

Related

Identify exception origin from exception properties in WPF (C# .Net) app

I am recently assigned a task to extend an existing WPF (C# .Net) application for an error handler. The handler is supposed to display a friendly message with possible easy solution for the user. It is required that I change nearly no code = I can only work in App.xaml.cs code behind. My approach is to try to identify the error from the stack trace and from the properties of the innermost exception. So far, I am using these three identifiers:
string identifierMethod= new System.Diagnostics.StackTrace(ex.GetBaseException()).GetFrame(0).GetMethod().Name;
string identifierObject = ex.GetBaseException().TargetSite.ReflectedType.FullName;
string identifierHResult = ex.GetBaseException().HResult.ToString();
//ex is the uppermost exception coming to App
I need to identify the root method and object where the exception originated. Combining these three seems to work for me but I don’t think it is very clean and robust and I fear there could be some exception that will have duplicate combination of these three identifiers. Sometimes the innermost exception’s stack trace is null, sometimes it seems to me the identifiers do not really describe the lowermost method or object constructor which caused the Exception.
I know I could ideally use Exception Data or Source properties assigning some identifiers in try catch block where the Exception originate but I simply cannot. I know similar question were asked but they only gave me what I have now.
Thanks a lot for any suggestions and ideas.
You can use Checked Exceptions to announce the caller methods about the callees' exceptions. And in caller methods, you can easily handle the exception by their types, identify the exception origin, and have a friendly message.
To add the Checked Exception feature into the C#, you can use this nugget package: Portia.Roslyn.CheckedException.

Useless Exceptions (NullReferenceException, KeyNotFoundException)

I find the C# exceptions very annoying, because they provide so less information. What is the reason for this?
NullReferenceException or KeyNotFoundExceptions are hard to debug and sometimes you don´t get a linenumber in the stacktrace. Why can the exception itself not provide more informations?
For example:
private Dictionary<string, object> Properties = null;
public void Process(string key)
{
var item = this.Properties[key];
....
}
When "Properties"is null I get a NullReferenceException:
"System.NullReferenceException: Object reference not set to an instance to an object"
Why I do not get:
"System.NullReferenceException: Object reference 'Properties' not set to an instance to an object"
This would be more usefull and the CLR does know, which reference is null.
The same when I pass a non existent key e.g. Process("dummy"):
"System.Collections.Generic.KeyNotFoundException: The given key was not present in the dictionary"
Why I do not get:
"System.Collections.Generic.KeyNotFoundException: The key 'dummy' was not present in the dictionary"
The CLR knows, which key was passed and not found.
I try to debug such errors (which illegal keys are passed) in an productive environment
and made the code more robust like:
private Dictionary<string, object> Properties = null;
public void Process(string key)
{
if (this.Properties != null)
{
if (this.Properties.ContainsKey(key))
{
var item = this.Properties[key];
...
}
else
{
throw new KeyNotFoundException(string.Format("The key '{0}' was not found.", key));
}
}
else
{
throw new NullReferenceException(string.Format("The object 'Properties' is null."));
}
}
But why I have to do this, normally the CLR could tell me what was going wrong in detail. I cannot wrap all codepieces like this to get more informations when an exception happens.
For your KeyNotFoundExceptions, you can create your own dictionary class that throws more meaningful messages (I recommend you try to extend KeyNotFoundException and throw that), or you can use TryGetValue and throw a meaningful exception.
The NullReferenceException one, however, is much more complicated: you assume that the CLR knows that the thing is called Properties, but it's not so simple: consider this.GetSomething(abc).DoSomething(), where GetSomething(abc) returns null. What is the object that's null? It doesn't have a name. And sometimes, especially in Release-optimized code, names for variables or other things that might be null are generated.
You should be debugging with test cases, Asserts, breakpoints, and other debug-mode code, not expecting that you can always get a good enough exception message to debug production code. E.g. even if you know that the key "dummy" was passed in, you might not have enough information to know why that key was bad, or was passed in.
Question: Why do exceptions provide less information than available?
Answer: Possible performance issues.
To produce a nice KeyNotFoundException, you need to call ToString(). This can take considerable time. For example, if I create Dictionary<StringBuilder, int>, failing to find a key would cause a (possibly huge) new memory block to be allocated and filled with data (in .NET 4.5 implementation). Furthermore, this can cause exception message to contain a few megabytes of text.
Question: Why not make exception messages more detailed in Debug mode?
Answer: Inconsistency is bad.
It is extremely difficult to fix bugs which can only be reproduced in Release mode. Getting string representation of keys only in Debug mode will cause diferent behavior:
ToString can throw exceptions.
Lazy programmers can preform checks on exception messages.
Question: But there are suggestions on UserVoice to improve the messages.
Answer: If you like them, vote for them.
I guess that meaningful NullReferenceException in a.b.c.d.e.f.g.h() chain is not top priority. It is annoying, but it has an easy workaround. If you think it is one of the most important problems, then go vote for it. But you may look around and find more interesting stuff to vote for.
In general, code which throws an exception doesn't know what's going to be done with the message. Conceptually, it might have been possible for an exception to include both Message and a DeveloperPrivateMessage properties, and specify that exceptions should refrain from placing in Message any information which could compromise security if revealed to the general public, and code receiving exceptions should refrain from persisting DeveloperPrivateMessage in any fashion which would expose it to untrusted personnel, but that would have complicated things. Instead, code that throws exceptions is expected to simply refrain from including any confidential data. Since dictionaries have no way of knowing whether keys might be used to store confidential data, that implies that keys should not be included in exception messages.
As for NullReferenceException, that's generally caught by a trap handler which may be able to determine that code was trying to execute a mov eax,[esi+8] when the ESI register was zero, but the trap handler would have no way of knowing where the value in ESI came from. If one says meh = Foo.Bar.Boom, and the Bar property returns null only after modifying Foo so that the next call won't return null, then by the time the system tries to access null.Boom, Foo.Bar won't be null. The best the system could do would be to say that "member Bar of some object was null", but that may not be very helpful.
Then you should add special handling to get this information. Remember everything comes at some cost. The more bloated you make exception handling (that shouldn't occur in the first place) - the larger the framework would have to be for every single case like this.
You really should consider these "Last chance exceptions" since you should never see them if coded correctly. Between the exception message and the stack trace that is provided - that should be enough information for your.
The responsibility of checking for null or if the key is missing is on you, the developer. The reason for this is optimization; if the default exceptions were more detailed like you would like, then the compiler would not be able to optimize as efficiently.
It's a trade-off. Adding null checks can be annoying, but it's how the language is designed.

Try Catch or If statement?

if you think there is a possibility of getting a null pointer exception, should you use an if statement to make sure the variable is not null, or should you just catch the exception?
I don't see any difference as you can put your logic to deal with the null pointer in the if statement, or in the catch block, so which one is best practise?
I would say ALWAYS use logic to catch the exception, not try/catch.
Try/Catch should be used when you validate but some strange thing happens and something causes an error so you can handle it more gracefully.
There is no single answer that will suffice here, it depends.
Let's take a few scenarios so you can see what I mean.
Scenario: Method that takes a reference type parameter that does not accept null
You're defining a method, it takes a reference type parameter, say a stream object, and you don't want to accept null as a legal input parameter.
In this case, I would say that the contract is that null is not a valid input. If some code does in fact call that method with a null reference, the contract is broken.
This is an exception, more specifically, it's an ArgumentNullException.
Example:
public void Write(Stream stream)
{
if (stream == null)
throw new ArgumentNullException("stream");
...
I would definitely not just let the code execute until it tries to dereference the stream in this case, instead crashing with a NullReferenceException, because at that point I lost all ability to react when I know the cause.
Q. Why can't I return false instead of throwing an exception?
A. Because a return value is easy to silently ignore, do you really want your "Write" methods to just silently skip writing because you made a snafu in the calling code, passing the wrong stream object or something that cannot be written to? I wouldn't!
Scenario: Method returns a reference to an object, sometimes there is no object
In this case the contract is that null is a legal result. In my opinion, null is something to avoid because it is quite hard to make sure you handle correctly everywhere, but sometimes it is the best way.
In this case I would make sure to if my way around the result, to ensure I don't crash when the null reference comes back.
Generalisation
If you take a close look at the above two scenarios, you'll note one thing:
In both cases it comes down to what is being expected, what the contract is.
If the contract says "not null", throw an exception. Don't fall back to the old-style API way of returning false because an exceptional problem should not be silently ignored, and littering the code with if statements to ensure every method call succeeds does not make for readable code.
If the contract says "null is entirely possible", handle it with if statements.
Advertising
For getting a better grip on null problems, I would also urge you to get ReSharper for you and your team, but please note that this answer can be applied to any type of exception and error handling, the same principles applies.
With it comes attributes you can embed into your project(s) to flag these cases, and then ReSharper will highlight the code in question.
public void Write([NotNull] Stream stream)
[CanBeNull]
public SomeObject GetSomeObject()
To read more about the contract attributes that ReSharper uses, see
ReSharper NullReferenceException Analysis and Its Contracts
Contract Annotations in ReSharper 7
Well. Exceptions are just that. Exceptions. They are thrown when something unforseen has happened and should not be part of the normal program flow.
And that's what is happening here. You expected the argument to be specified when it's not. That is unexpected and you should therefore throw your own exception informing the user of that. If you want to get bonus points you can also include the reason to WHY the argument must be specified (if it's not obvious).
I've written a series of posts about exceptions: http://blog.gauffin.org/2013/04/what-is-exceptions/
From a performance standpoint it really depends what you're doing. The performance impact from a try/catch block when no exception is thrown is minimal (and if you really need that last few percent of performance, you probably should rewrite that part of your code in C++ anyway). Throwing exceptions does have a major impact on simpler operations such as string manipulation; but once you get file/database operations in the loop they're so much slower that again it becomes a trivial penalty. Throwing across an App Domain will have a non-trivial impact on just about anything though.
Performance in Operations/second:
Mode/operation Empty String File Database Complex
No exception 17,748,206 267,300 2,461 877 239
Catch without exception 15,415,757 261,456 2,476 871 236
Throw 103,456 68,952 2,236 864 236
Rethrow original 53,481 41,889 2,324 852 230
Throw across AppDomain 3,073 2,942 930 574 160
Additional test results along with the source for the tests is available from the article Performance implications of Exceptions in .NET
I would rather suggest you use if-statement for NullReference exception. For other exception, try-catch should be good enough.
The reason I suggest if-statement for NullReference exception is because C# will not tell which variable is null. if that line has more than one object could be null, you will loss track. If you are using if-statement, you can have better logging to help you get the enough information.
The main Question is if it is a good idea to have methods returning Null at all, personally i do not have any problem with this, but as soon as you try to access modifiers of an object returned from this method and you forget to check if it is assigned this becomes an issue.
Ken has a good answer about this:
If you are always expecting to find a value then throw the exception
if it is missing. The exception would mean that there was a problem.
If the value can be missing or present and both are valid for the
application logic then return a null.
See this disscussion abou tthis issue:
Returning null is usually the best idea if you intend to indicate that
no data is available.
An empty object implies data has been returned, whereas returning null
clearly indicates that nothing has been returned.
Additionally, returning a null will result in a null exception if you
attempt to access members in the object, which can be useful for
highlighting buggy code - attempting to access a member of nothing
makes no sense. Accessing members of an empty object will not fail
meaning bugs can go undiscovered.
Some further reading:
No Null Beyond Method Scope
Should We Return Null From Our Methods?
using try catch for the statements is not an good idea. because when you use try catch them it seems that if some error comes the code will not turninate the application. but if you are sure about what kind of error can come you can tap the error at that point. that will not produce any unknown errors. for example.
string name = null;
here i am going to use the name variable and i am sure that this will throw Null Refrance Error .
try
{
Console.writeLine("Name ={0}",name);
}
catch (NullRefranceException nex)
{
//handle the error
}
catch(Exception ex)
{
// handle error to prevent application being crashed.
}
This is not a good practice while you can handle this kind of error and make your code more readable. like.
if(name !=null)
Console.writeLine("Name ={0}",name);
In my experience using if is better but only if you actually expect a null reference pointer. Without any bit of code or context its difficult to say when one option is better than the other.
There's also a matter of optimization - code in try-catch blocks won't be optimized.
In general, try-catch blocks are great because they will break (move to the catch statement) whenever the exception occurs. If-else blocks rely on you predicting when the error will happen.
Also, catch blocks won't stop your code from halting when an error is hit.
Its always better to use Try Catch other than if else
Here Exceptions are two types namely handled and UN-handled exceptions
Even if u want to handle some function when the Exception u can handle it...
Handled exception always allows you to write some implementations inside the Catch block
Eg. An Alert Message, A new Function to handle when such exception occurs.

How to use Java-style throws keyword in C#?

In Java, the throws keyword allows for a method to declare that it will not handle an exception on its own, but rather throw it to the calling method.
Is there a similar keyword/attribute in C#?
If there is no equivalent, how can you accomplish the same (or a similar) effect?
The op is asking about the C# equivalent of Java's throws clause - not the throw keyword. This is used in method signatures in Java to indicate a checked exception can be thrown.
In C#, there is no direct equivalent of a Java checked exception. C# has no equivalent method signature clause.
// Java - need to have throws clause if IOException not handled
public void readFile() throws java.io.IOException {
...not explicitly handling java.io.IOException...
}
translates to
// C# - no equivalent of throws clause exceptions are unchecked
public void ReadFile()
{
...not explicitly handling System.IO.IOException...
}
In Java, you must either handle an exception or mark the method as one that may throw it using the throws keyword.
C# does not have this keyword or an equivalent one, as in C#, if you don't handle an exception, it will bubble up, until caught or if not caught it will terminate the program.
If you want to handle it then re-throw you can do the following:
try
{
// code that throws an exception
}
catch(ArgumentNullException ex)
{
// code that handles the exception
throw;
}
Yes this is an old thread, however I frequently find old threads when I am googling answers so I figured I would add something useful that I have found.
If you are using Visual Studio 2012 there is a built in tool that can be used to allow for an IDE level "throws" equivalent.
If you use XML Documentation Comments, as mentioned above, then you can use the <exception> tag to specify the type of exception thrown by the method or class as well as information on when or why it is thrown.
example:
/// <summary>This method throws an exception.</summary>
/// <param name="myPath">A path to a directory that will be zipped.</param>
/// <exception cref="IOException">This exception is thrown if the archive already exists</exception>
public void FooThrowsAnException (string myPath)
{
// This will throw an IO exception
ZipFile.CreateFromDirectory(myPath);
}
Here is an answer to a similar question I just found on bytes.com:
The short answer is no. There are no checked exceptions in C#. The
designer of the language discusses this decision in this interview:
http://www.artima.com/intv/handcuffs.html
The nearest you can get is to use the tags in your XML
documentation, and distribute NDoc generated docs with your
code/assemblies so that other people can see which exceptions you throw
(which is exactly what MS do in the MSDN documentation). You can't rely
on the compiler to tell you about unhandled exceptions, however, like
you may be used to in java.
After going through most of the answers here, I'd like to add a couple of thoughts.
Relying on XML Documentation Comments and expecting others to rely on is a poor choice. Most C# code I've come across does not document methods completely and consistently with XML Documentation Comments. And then there's the bigger issue that without checked exceptions in C#, how could you document all exceptions your method throws for the purpose of your API user to know how to handle them all individually? Remember, you only know about the ones you throw yourself with the throw keyword in your implementation. APIs you're using inside your method implementation might also throw exceptions that you don't know about because they might not be documented and you're not handling them in your implementation, so they'll blow up in face of the caller of your method. In other words, these XML documentation comments are no replacement for checked exceptions.
Andreas linked an interview with Anders Hejlsberg in the answers here on why the C# design team decided against checked exceptions. The ultimate response to the original question is hidden in that interview:
The programmers protect their code by writing try finally's everywhere, so they'll back out correctly if an exception occurs, but they're not actually interested in handling the exceptions.
In other words, nobody should be interested in what kind of exception can be expected for a particular API as you're always going to catch all of them everywhere. And if you want to really care about particular exceptions, how to handle them is up to you and not someone defining a method signature with something like the Java throws keyword, forcing particular exception handling on an API user.
--
Personally, I'm torn here. I agree with Anders that having checked exceptions doesn't solve the problem without adding new, different problems. Just like with the XML documentation comments, I rarely see C# code with everything wrapped in try finally blocks. It feels to me though this is indeed your only option and something that seems like a good practice.
Actually not having checked exceptions in C# can be considered a good or bad thing.
I myself consider it to be a good solution since checked exceptions provide you with the following problems:
Technical Exceptions leaking to the business/domain layer because you cannot handle them properly on the low level.
They belong to the method signature which doesn't always play nice with API design.
Because of that in most bigger applications you will see the following pattern often when checked Exceptions occur:
try {
// Some Code
} catch(SomeException ex){
throw new RuntimeException(ex);
}
Which essentially means emulating the way C#/.NET handles all Exceptions.
You are asking about this :
Re-throwing an Exception
public void Method()
{
try
{
int x = 0;
int sum = 100/x;
}
catch(DivideByZeroException e)
{
throw;
}
}
or
static void Main()
{
string s = null;
if (s == null)
{
throw new ArgumentNullException();
}
Console.Write("The string s is null"); // not executed
}
There are some fleeting similarities between the .Net CodeContract EnsuresOnThrow<> and the java throws descriptor, in that both can signal to the caller as the type of exception which could be raised from a function or method, although there are also major differences between the 2:
EnsuresOnThrow<> goes beyond just stating which exceptions can be thrown, but also stipulates the conditions under which they are guaranteed to be thrown - this can be quite onerous code in the called method if the exception condition isn't trivial to identify. Java throws provides an indication of which exceptions could be thrown (i.e. IMO the focus in .Net is inside the method which contracts to prove the throw, whereas in Java the focus shifts to the caller to acknowledge the possibility of the exception).
.Net CC doesn't make the distinction between Checked vs Unchecked exceptions that Java has, although the CC manual section 2.2.2 does mention to
"use exceptional postconditions only for those exceptions that a caller
should expect as part of the API"
In .Net the caller can determine whether or not to do anything with the exception (e.g. by disabling contracts). In Java, the caller must do something, even if it adds a throws for the same exception on its interface.
Code Contracts manual here
If the c# method's purpose is to only throw an exception (like js return type says) I would recommend just return that exception. See the example bellow:
public EntityNotFoundException GetEntityNotFoundException(Type entityType, object id)
{
return new EntityNotFoundException($"The object '{entityType.Name}' with given id '{id}' not found.");
}
public TEntity GetEntity<TEntity>(string id)
{
var entity = session.Get<TEntity>(id);
if (entity == null)
throw GetEntityNotFoundException(typeof(TEntity), id);
return entity;
}
For those wondering, you do not even need to define what you catch to pass it on to the next method. In case you want all your error handling in one main thread you can just catch everything and pass it on like so:
try {
//your code here
}
catch {
//this will throw any exceptions caught by this try/catch
throw;
}

throw new Exception vs Catch block

Is there any behavioural difference between:
if (s == null) // s is a string
{
throw new NullReferenceException();
}
And:
try
{
Console.Writeline(s);
}
catch (NullReferenceException Ex)
{ // logic in here
}
Both throw exceptions of null object, if s is null. The first example is more readable as it shows exactly where the error occurs (the exception bit is right next to the line which will cause the exception).
I have seen this coding style a lot on various blogs by various coders of all sorts of skill levels, but why not just perform the main logic by checking if s is not null and thus save the exception from ever being raised? Is there a downside to this approach?
Thanks
No, Console.WriteLine(null) won't throw an exception. It will just print nothing out. Now assuming you meant something like:
Console.WriteLine(s.Length);
then it makes sense... and you should use the first form. Exceptions should occur when you can't predict them ahead of time with your current information. If you can easily work out that something's wrong, it makes no sense to try an operation which is bound to fail. It leads to code which is harder to understand and performs worse.
So NullReferenceException, ArgumentNullException and the like shouldn't be caught unless they're due to a nasty API which sometimes throws exceptions which you can handle, but which shouldn't really be being thrown in the first place. This is why in Code Contracts, the default behaviour for a failed contract is to throw an exception which you can't catch explicitly, other than by catching everything (which is typically somewhere at the top of the stack).
As Jon Skeet already mentioned, Console.WriteLine (null) won't throw an exception.
Next to that, I'd like to say that you should 'fail fast'. That means that you have to put 'guard' clauses in your methods, and check the arguments that have been given in your methods if they can be considered to be valid.
This allows you to throw an exception yourself, and give an additional message which will be helpfull when debugging. The message can give a clear indication on what was wrong, and that is much handier then if you're faced with a NullReferenceException that has been thrown without any good information in it's message property.
If you are writing a class library there may be occasions when you know that if a certain parameter contains a null value, that may cause trouble further down the line. In those cases I usually find it to be a good idea to throw an exception (even though I would probably use ArgumentNullException for that case) to make the user of the class library aware of this as early and clearly as possible.
Exceptions are not always a bad thing.
Jon Skeet is right but, more generally, it's all a question of semantic.
If the situation has some applicative meaning (number out of bound, date of birth in the future, etc) you may want to test for it before doing any operation and throw a custom exception (that is one with meaning for your application).
If the situation is truly "exceptional", just write the code as if the given value were correct. See, if you put the test, you will do it everytime, knowing that the VM will do it anyway in case it needs to throw an exception. From a performance point of view, if the error happens to have a statistically small occurence, it makes no sense.
If you're taking a Design By Contract type approach to things then a piece of code can specify that it throws exceptions in order to specify its contract and to enforce it. The other half is, of course, calling code recognising the contract and fulfilling it.
In this case it would mean that if you know a method will throw an exception if you pass in null (i.e. its contract is that you don't pass nulls) then you should check before calling it.
Jon Skeet says that the method won't throw an exception anyway. That may or may not be true but the principle of guarding for method contract stands (which I believe was the point of your question).

Categories

Resources