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 ....
Related
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.
Is there an operator to simplify this operation in C# to avoid null pointer exceptions?
obj == null ? null : obj.Property;
Something like
obj?.Property;
I really want to get rid of NullReferenceExeptions
As #canton7 said, you answered your own question.
The ?. operator actually exists in C#
Here's a small example showing how it prevents the NullReferenceException
public class Program
{
public static void Main(string[] args)
{
List<string> list = GetList();
Console.WriteLine($"{list?.Count}");
Console.ReadKey();
}
public static List<string> GetList()
{
return null;
}
}
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...
}
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);
}
I have the following code:
if (Session["CurrentUrl"] != null & Session["CurrentHost"] != null)
I use this in many places. I am wondering if anyone can think of a way to optimize the C# code just to make things slight more clear.
This seems like a prime candidate for an extension method:
public static class SessionExtensions
{
public static bool HasHostAndUrl(this HttpSessionState session)
{
return session["CurrentUrl"] != null && session["CurrentHost"] != null;
}
}
And then:
if (Session.HasHostAndUrl()) { /* ... */ }
if (HostAndUrlExist()) {
...
}
public boolean HostAndUrlExist() {
return Session["CurrentUrl"] != null && Session["CurrentHost"] != null
}
Make a method to return true or false
If you have groups of session variables that you often use together, consider storing them as an object instead of as a set of primitive types.
You can make a method that takes one or more strings, like this:
public boolean SessionObjectsPresent(params string[] names) {
foreach (var name in names) {
if (Session[name] == null) return false
}
return true;
}
if (SessionObjectsPresent("CurrentHost", "CurrentUrl")) {
// ...
}
The benefit of this approach becomes evident when you need to test session for other things:
if (SessionObjectsPresent("CurrentUser", "LastEditTime")) {
// ...
}
Several ways to improve, like abstract a method with a meaningful name, or extract a interface ISession to make it more unit testable.