Automatically raising an exception if value is null - c#

In my class I've done this:
private void RaiseExceptionIfNull(object o, string error)
{
if (o == null) {
throw new System.NullReferenceException(error + " is null " +
"(should never be null)");
}
}
And then in all my methods, I'm doing stuff like this:
RaiseExceptionIfNull(cbAjaxFinished, "Callback Ajax Finished");
RaiseExceptionIfNull(j, "Result conversion");
... all of this because I'd like to raise an exception if value is null in one line (with clean code).
I was wondering if there's already a way to raise an exception like I do, but in C# (I'm a newbie in this area) (kind of "assert() in C", but with custom exception).

In your case, I would throw an ArgumentNullException instead of using NullReferenceException since your are checking for an argument to be invalid because it's null. With extension methods, you can achieve a one-liner check very easily:
// value types should be excluded as they can't be null
// hence the "where T : class" clause
internal static void ThrowIfNull<T>(this T obj, String parameterName) where T : class
{
if (obj == null)
throw new ArgumentNullException(parameterName);
}
Then, in your methods use the extension as follows:
public void MyFunc(Object obj)
{
obj.ThrowIfNull(nameof(obj));
// Your implementation...
}

Related

When can a null check throw a NullReferenceException

I know this might seem impossible at first and it seemed that way to me at first as well, but recently I have seen exactly this kind of code throw a NullReferenceException, so it is definitely possible.
Unfortunately, there are pretty much no results on Google that explain when code like foo == null can throw a NRE, which can make it difficult to debug and understand why it happened. So in the interest of documenting the possible ways this seemingly bizarre occurrence could happen.
In what ways can this code foo == null throw a NullReferenceException?
in C# you can overload operators to add custom logic on some comparison like this. For example:
class Test
{
public string SomeProp { get; set; }
public static bool operator ==(Test test1, Test test2)
{
return test1.SomeProp == test2.SomeProp;
}
public static bool operator !=(Test test1, Test test2)
{
return !(test1 == test2);
}
}
then this would produce a null reference exception:
Test test1 = null;
bool x = test1 == null;
One example is with getters:
class Program
{
static void Main(string[] args)
{
new Example().Test();
}
}
class Example
{
private object foo
{
get => throw new NullReferenceException();
}
public void Test()
{
Console.WriteLine(foo == null);
}
}
This code will produce a NullReferenceException.
While quite esoteric, it is possible to cause this type of behavior via custom implementations of DynamicMetaObject. This would be a rare but interesting example of where this could occur:
void Main()
{
dynamic foo = new TestDynamicMetaObjectProvider();
object foo2 = 0;
Console.WriteLine(foo == foo2);
}
public class TestDynamicMetaObjectProvider : IDynamicMetaObjectProvider
{
public DynamicMetaObject GetMetaObject(Expression parameter)
{
return new TestMetaObject(parameter, BindingRestrictions.Empty, this);
}
}
public class TestMetaObject : DynamicMetaObject
{
public TestMetaObject(Expression expression, BindingRestrictions restrictions)
: base(expression, restrictions)
{
}
public TestMetaObject(Expression expression, BindingRestrictions restrictions, object value)
: base(expression, restrictions, value)
{
}
public override DynamicMetaObject BindBinaryOperation(BinaryOperationBinder binder, DynamicMetaObject arg)
{
// note it doesn't have to be an explicit throw. Any improper property
// access could bubble a NullReferenceException depending on the
// custom implementation.
throw new NullReferenceException();
}
}
Not literally your code, but awaiting a null task will also throw:
public class Program
{
public static async Task Main()
{
var s = ReadStringAsync();
if (await s == null)
{
Console.WriteLine("s is null");
}
}
// instead of Task.FromResult<string>(null);
private static Task<string> ReadStringAsync() => null;
}
Do note however that the debugger can get the location of throwing statements wrong. It might show the exception thrown at the equality check, while it occurs at earlier code.
foo == null does indeed to operator overload resolution, and the operator in question didn't handle being passed a null. We are starting to consider writing foo == null obsolete and preferring (taking a page from Visual Basic) foo is null or !(foo is null) which is soon to be full is not null to explicitly inline a null pointer check.
Fix your operator== implemenation. It shouldn't throw, but it is.

Does Any() extension method handle null values?

In the below program, (!testlist.Any()) throws an argument null exception. Doesn't Any() extension method by default handle null values ?
What is the right approach for this ? Should a null check be added before Any() when List<int> is used as a parameter in a method ?
public class Program
{
public static void Main(string[] args)
{
Console.WriteLine("Hello, world!");
foo(null);
}
public static void foo(List<int> testlist)
{
if (!testlist.Any())
{
Console.WriteLine("testlist is empty!");
}
}
}
Should a null check be added before Any() when List is used as a
parameter in a method ?
Yes, that's the right approach. The method should fail fast with a meaningful message.
public static void foo(List<int> testlist)
{
if(testlist == null)
throw new ArgumentNullException(nameof(testlist), $"{nameof(testlist)} must not be null");
if (!testlist.Any())
{
Console.WriteLine("testlist is empty!");
}
}
Of course Enumerable.Any does not handle this for you. It might be a bug that null was passed to this method or it might be a viable option. Only you know.
The exception is also documented:
"ArgumentNullException: source is null."
If you don't want to throw it but you want to accept null, just handle this case:
if(testlist == null || !testlist.Any())
{
Console.WriteLine("testlist is null or empty!");
}
else ....

What is the best way to extend null check?

You all do this:
public void Proc(object parameter)
{
if (parameter == null)
throw new ArgumentNullException("parameter");
// Main code.
}
Jon Skeet once mentioned that he sometimes uses the extension to do this check so you can do just:
parameter.ThrowIfNull("parameter");
So I come of with two implementations of this extension and I don't know which one is the best.
First:
internal static void ThrowIfNull<T>(this T o, string paramName) where T : class
{
if (o == null)
throw new ArgumentNullException(paramName);
}
Second:
internal static void ThrowIfNull(this object o, string paramName)
{
if (o == null)
throw new ArgumentNullException(paramName);
}
What do you think?
I tend to stick to the ubiquitous Guard class for this:
static class Guard
{
public static void AgainstNulls(object parameter, string name = null)
{
if (parameter == null)
throw new ArgumentNullException(name ?? "guarded argument was null");
Contract.EndContractBlock(); // If you use Code Contracts.
}
}
Guard.AgainstNulls(parameter, "parameter");
And shy away from extending object, plus to the naked eye a method call on a null object seems nonsensical (although I know it is perfectly valid to have null method calls against extension methods).
As for which is best, I'd use neither. They both have infinite recursion. I'd also not bother guarding the message parameter, make it optionally null. Your first solution will also not support Nullable<T> types as the class constraint blocks it.
Our Guard class also has the Contract.EndContractBlock() call after it for when we decide to enable Code Contracts, as it fits the "if-then-throw" structure that is required.
This is also a perfect candidate for a PostSharp aspect.
I'd use internal static void ThrowIfNull<T>(this T o, string paramName) where T : class. I won't use internal static void ThrowIfNull(this object o, string paramName) because it might do boxing.
As of .NET 6, now we have the static method ThrowIfNull in the System.ArgumentNullException class with the following signature:
ThrowIfNull(object? argument, string? paramName = null);
Therefore, instead of writing:
if (value == null)
{
throw new System.ArgumentNullException(nameof(value));
}
Now we can simply write:
System.ArgumentNullException.ThrowIfNull(value);
The docs: https://learn.microsoft.com/en-us/dotnet/api/system.argumentnullexception.throwifnull?view=net-6.0
The implementation of this new method takes advantage of the System.Runtime.CompilerServices.CallerArgumentExpressionAttribute attribute to simplify this further, by not requiring the developer to explicitly provide the name of the parameter that's being guarded.
The discussion that ended up introducing this new API can be found here:
https://github.com/dotnet/runtime/issues/48573
The PR that introduced it in the .NET 6 code base can be found here:
https://github.com/dotnet/runtime/pull/55594
I would do this way to avoid hardcoding parameter names. Tomorrow it can change, and you have more work then:
public static void ThrowIfNull<T>(this T item) where T : class
{
var param = typeof(T).GetProperties()[0];
if (param.GetValue(item, null) == null)
throw new ArgumentNullException(param.Name);
}
And call it:
public void Proc(object parameter)
{
new { parameter }.ThrowIfNull(); //you have to call it this way.
// Main code.
}
The performance hit is trivial (on my mediocre computer it ran for 100000 times just under 25 ms), much faster than Expression based approach seen typically
ThrowIfNull(() => resource);
One such here. But surely don't use this if you cant afford that much hit..
You can also extend this for properties of objects.
new { myClass.MyProperty1 }.ThrowIfNull();
You can cache property values to improve performance further as property names don't change during runtime.
See this question additionally: Resolving a parameter name at runtime
What about using Expression Trees (from Visual Studio Magazine):
using System;
using System.Linq.Expressions;
namespace Validation
{
public static class Validator
{
public static void ThrowIfNull(Expression<Func<object>> expression)
{
var body = expression.Body as MemberExpression;
if( body == null)
{
throw new ArgumentException(
"expected property or field expression.");
}
var compiled = expression.Compile();
var value = compiled();
if( value == null)
{
throw new ArgumentNullException(body.Member.Name);
}
}
public static void ThrowIfNullOrEmpty(Expression<Func<String>> expression)
{
var body = expression.Body as MemberExpression;
if (body == null)
{
throw new ArgumentException(
"expected property or field expression.");
}
var compiled = expression.Compile();
var value = compiled();
if (String.IsNullOrEmpty(value))
{
throw new ArgumentException(
"String is null or empty", body.Member.Name);
}
}
}
}
Used like this:
public void Proc(object parameter1, object parameter2, string string1)
{
Validator.ThrowIfNull(() => parameter1);
Validator.ThrowIfNull(() => parameter2);
Validator.ThrowIfNullOrEmpty(() => string1);
// Main code.
}
Based on C# 10, I use the ThrowIfNull extension method:
public static class CheckNullArgument
{
public static T ThrowIfNull<T>(this T argument)
{
ArgumentNullException.ThrowIfNull(argument);
return argument;
}
}
Usage:
public class UsersController
{
private readonly IUserService _userService;
public UsersController(IUserService userService)
{
_userService = userService.ThrowIfNull();
}
}
Second one seems more elegant way of handling the same. In this case you can put restriction on every managed object.
internal static void ThrowIfNull(this object o, string paramName)
{
if (o == null)
throw new ArgumentNullException(paramName);
}

Instantiate new object based on type parameter

I am trying to throw an exception based on the exception type parameter passed to the method.
Here is what I have so far but I don't want to specify each kind of exception:
public void ThrowException<T>(string message = "") where T : SystemException, new()
{
if (ConditionMet)
{
if(typeof(T) is NullReferenceException)
throw new NullReferenceException(message);
if (typeof(T) is FileNotFoundException)
throw new FileNotFoundException(message);
throw new SystemException(message);
}
}
Ideally I want to do something like new T(message) given I have a base type of SystemException I would have thought this was somehow possible.
I don't think that you can do this using gerics alone. You would need to use reflection. Something like:
throw (T)Activator.CreateInstance(typeof(T),message);
As others stated, this can only be done with reflection. But you could drop the type parameter and pass the instantiated exception to the function:
public void ThrowException(Exception e)
{
if (ConditionMet)
{
if(e is NullReferenceException || e is FileNotFoundException)
{
throw e;
}
throw new SystemException(e.Message);
}
}
Usage:
// throws a NullReferenceException
ThrowException(new NullReferenceException("message"));
// throws a SystemException
ThrowException(new NotSupportedException("message"));
You can use
Activator.CreateInstance(typeof(T),message);
More at http://msdn.microsoft.com/en-us/library/wcxyzt4d.aspx

IsAssignableFrom or AS?

I have next code:
private T CreateInstance<T>(object obj) // where T : ISomeInterface, class
{
...
if (!typeof(T).IsAssignableFrom(obj.GetType())) { throw ..; }
return (T)obj;
}
Can it be replaced with this:
T result = obj as T;
if (result == null) { throw ..; }
return result;
If not - why?
What about if (!(bar is T)) { throw ..; }
Alternatively if you don't need your own exception message the simplest answer is just to do:
return (T)obj;
The reason if that if it's not castable an InvalidCastException will be thrown and the return ignored. Unless you're adding some more logic or a custom error message there's no need to do a check and throw your own exception.
Another variant:
private T CreateInstance<T>(object obj) where T : ISomeInterface // as OP mentioned above
{
...
T result = obj as T;
if (result == null)
{ throw ..; }
else
return result;
}
Yes you can use your as operator code there instead of the original code, so long as T is a reference type or nullable.
as is the recommended way of casting in C# (see item 3 of Effective C#, by Bill Wagner)
From system.type.isassignablefrom:
[returns] true if c and the current Type represent the same type, or if the current Type is in the inheritance hierarchy of c, or if the current Type is an interface that c implements, or if c is a generic type parameter and the current Type represents one of the constraints of c. false if none of these conditions are true, or if c is null.
From 7.10.11 of the C# spec:
In an operation of the form E as T, E must be an expression and T must be a reference type, a type parameter known to be a reference type, or a nullable type
So you can see that they do comparable checks.
Maybe this (less brackets, better readability)
if (obj is T)
{
return (T)obj;
}
else
throw new ...
EDITED
by reduced number of brackets I originally meant inverted check: ie
if (obj is T)
instead of
if (!(obj is T))
so final version can be
if (obj is T)
{
return (T)obj;
}
throw new ...
or
if (obj is T)
{
return (T)obj;
}
else
{
throw new ...
}
See this post
The second one is safe...because at the first one if obj is null you will get exception (obj.GetType() --> NullReferenceException).
When you place "is" and then "as" is cause performance issues..
The class constraint where T : class allows you to use the as T statement.
private T CreateInstance<T>(object obj) where T : class
{
if (!(obj is T)) { throw new ArgumentException("..."); }
return obj as T;
}
or
private T CreateInstance<T>(object obj)
{
if (!(obj is T)) { throw new ArgumentException("..."); }
return (T)obj;
}
You're probably looking for the is keyword, with the syntax expression is type
Documentation describes it as performing the checks you want:
An is expression evaluates to true if
both of the following conditions are
met:
• expression is not null.
• expression
can be cast to type. That is, a cast
expression of the form
(type)(expression) will complete
without throwing an exception.
Edit
However, if instead of just working out whether you can cast something before you try, the as keyword is probably your best solution as you describe in your post.
The following code would perform the same function though...
try
{
T result = (T)obj;
return result;
}
catch (InvalidCastException ex)
{
// throw your own exception or deal with it in some other way.
}
Which method you prefer is up to you...
IsAssignableFrom used by this scene:
foreach (PropertyInfo property in GetType().GetProperties())
{
if (typeof(SubPresenter).IsAssignableFrom(property.PropertyType))
{//Do Sth.}
}
Just for the developers who like to play the numbers game (who doesn't!).
Below you'll find a performance comparison test for IsAssignableFrom vs. As. Of course this will only count if you have an instance.
The result of the test (one million attempts):
IsAssignableFrom: 146 ms elapsed
AsOperator: 7 ms elapsed
[TestMethod]
public void IsAssignableFromVsAsPerformanceTest()
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
int attempts = 1000000;
string value = "This is a test";
for (int attempt = 0; attempt < attempts; attempt++) {
bool isConvertible = typeof(IConvertible).IsAssignableFrom(value.GetType());
}
stopwatch.Stop();
Console.WriteLine("IsAssignableFrom: {0} ms elapsed", stopwatch.ElapsedMilliseconds);
stopwatch.Restart();
for (int attempt = 0; attempt < attempts; attempt++) {
bool isConvertible = value as string != null;
}
stopwatch.Stop();
Console.WriteLine("AsOperator: {0} ms elapsed", stopwatch.ElapsedMilliseconds);
}
It may have been intended to handle cases where a conversion constructor would allow the operation, but apparently IsAssignableFrom doesn't handle that either. Don't see anything that can handle that. So I don't see how to check for cases like this:
class Program
{
static void Main(string[] args)
{
B bValue = new B(123);
Console.WriteLine(typeof(A).IsAssignableFrom(bValue.GetType()));
//Console.WriteLine(bValue is A);
//Console.WriteLine(bValue as A == null);
A aValue = bValue;
Console.WriteLine(aValue.ToString());
}
}
class A
{
string value;
public A(string value)
{
this.value = value;
}
public override string ToString()
{
return value;
}
}
class B
{
int value;
public B(int value)
{
this.value = value;
}
public static implicit operator A(B value)
{
return new A(value.value.ToString());
}
}
In the end, I don't see any reason why you wouldn't want to use your version of the code, unless you want the code to throw an exception when obj is null. That's the only difference I can see. obj.GetType() will throw an null reference exception when obj is null instead of throwing the specified exception.
Edit: I see now your version of the code will not compile if T can be a value type, but the other suggested solution like "if (obj is T) return (T)obj;" will compile. So I see why your suggested alternative will not work, but I don't see why you couldn't use "is".
Or even better because its easer to read true conditionals.
if(obj is T){
//Create instance.
}
else{
throw new InvalidArgumentException("Try Again");
}

Categories

Resources