I've noticed this code crops up a lot in my constructors:
if (someParam == null) throw new ArgumentNullException("someParam");
if (someOtherParam == null) throw new ArgumentNullException("someOtherParam");
...
I have a few constructors where several things are injected and must all be non-null. Can anyone think of a way to streamline this? The only thing I can think of is the following:
public static class ExceptionHelpers
{
public static void CheckAndThrowArgNullEx(IEnumerable<KeyValuePair<string, object>> parameters)
{
foreach(var parameter in parameters)
if(parameter.Value == null) throw new ArgumentNullException(parameter.Key);
}
}
However, the usage of that would be something like:
ExceptionHelper.CheckAndThrowArgNullEx(new [] {
new KeyValuePair<string, object>("someParam", someParam),
new KeyValuePair<string, object>("someOtherParam", someOtherParam),
... });
... which doesn't really help streamline the code. Tuple.Create() instead of KVPs doesn't work because Tuple's GTPs aren't covariant (even though IEnumerable's GTP is). Any ideas?
Update for C# 7
You can use a throw expression with the null coalescing operator. Here is an example from that page:
public string Name
{
get => name;
set => name = value ??
throw new ArgumentNullException(paramName: nameof(value), message: "New name must not be null");
}
Original Answer
Personally, I use the ThrowIfNull extension method. I don't know who to credit but I definitely didn't invent it. It's nice because you can do assignment with the return value:
public static T ThrowIfNull<T>(this T argument, string argumentName)
{
if (argument == null)
{
throw new ArgumentNullException(argumentName);
}
return argument;
}
Usage:
this.something = theArgument.ThrowIfNull("theArgument");
// or in C# 6
this.something = theArgument.ThrowIfNull(nameof(theArgument));
(Although some people think it's weird to call an extension method on a null instance)
If you really want to check more than one argument at a time, your example might be more streamlined if you used a params signature like so:
public static void CheckAndThrowArgNullEx(params object[] argsAndNames)
{
for (int i = 0; i < argsAndNames.Length; i += 2)
{
if (argsAndNames[i] == null)
{
string argName = (string)argsAndNames[i + 1];
throw new ArgumentNullException(argName);
}
}
}
and the usage would be:
CheckAndThrowArgNullEx(arg1, "arg1", arg2, "arg2");
// or in C# 6
CheckAndThrowArgNullEx(arg1, nameof(arg1), arg2, nameof(arg2));
On second thought, as KeithS mentions in the comments, it would probably be better to implement this as a set of overloads rather than using params object[] like this:
static void Check(object arg1, string arg1Name) { ... }
static void Check(object arg1, string arg1Name, object arg2, string arg2Name) { ... }
// and so on...
Try this: One line.
accounts = accounts ?? throw new ArgumentNullException(nameof(accounts));
Also, use nameof(), if the variable is ever renamed you will not have to hunt down all the "variable"s, let nameof() do that.
.NET 6 and beyond
There is a new method in .NET API ArgumentNullException.ThrowIfNull(someParameter).
This method is probably the best option which you can get.
C# 11 (currently as proposal)
Use new Bang Bang operator !! on a parameter to implicit check for null.
public string SomeFunction(Foo foo!!)
{
// here, foo is already checked for null
// ArgumentNullException(nameof(foo)) is thrown when foo = null
return $"Here is {foo.Bar}";
}
TL;DR
The compiler will emit this code for every !! use
if (someArgument is null)
{
throw new ArgumentNullException(nameof(someArgument));
}
Our SomeFunction will be transformed into
public string SomeFunction(Foo foo!!)
{
if (foo is null)
{
throw new ArgumentNullException(nameof(foo));
}
return $"Here is {foo.Bar}";
}
There are several way to go about this.
Option A:
Break your functions into two - validation and implementation (you can see examples of this in Jon Skeet's EduLinq).
Option B:
Use code contracts that expect the parameters to be non-null.
Option C:
Using aspect oriented technologies such as code weaving to extract these checks out into an aspect. (as J Torres answered).
Option D:
Use Spec#, as CodeInChaos commented.
Option E:
???
Upticks for most of you guys; your answers contributed to the solution I finally arrived at, which incorporated bits and pieces but ultimately is different from all of them.
I created a couple of static methods that work on lambda expressions of a specific form (EDIT - small change; the methods can't be generic or they will require all expressions to return the same type. Func is fine instead, with an extra condition in the GetName method to unwrap the cast):
public static class ExpressionReader
{
/// <summary>
/// Gets the name of the variable or member specified in the lambda.
/// </summary>
/// <param name="expr">The lambda expression to analyze.
/// The lambda MUST be of the form ()=>variableName.</param>
/// <returns></returns>
public static string GetName(this Expression<Func<object>> expr)
{
if (expr.Body.NodeType == ExpressionType.MemberAccess)
return ((MemberExpression) expr.Body).Member.Name;
//most value type lambdas will need this because creating the
//Expression from the lambda adds a conversion step.
if (expr.Body.NodeType == ExpressionType.Convert
&& ((UnaryExpression)expr.Body).Operand.NodeType
== ExpressionType.MemberAccess)
return ((MemberExpression)((UnaryExpression)expr.Body).Operand)
.Member.Name;
throw new ArgumentException(
"Argument 'expr' must be of the form ()=>variableName.");
}
}
public static class ExHelper
{
/// <summary>
/// Throws an ArgumentNullException if the value of any passed expression is null.
/// </summary>
/// <param name="expr">The lambda expressions to analyze.
/// The lambdas MUST be of the form ()=>variableName.</param>
/// <returns></returns>
public static void CheckForNullArg(params Expression<Func<object>>[] exprs)
{
foreach (var expr in exprs)
if(expr.Compile()() == null)
throw new ArgumentNullException(expr.GetName());
}
}
... which can be used thusly:
//usage:
ExHelper.CheckForNullArg(()=>someParam, ()=>someOtherParam);
This reduces the boilerplate to one line, without third-party tools. The ExpressionReader, and thus the exception-generating method, work on any lambda of the form ()=>variableName that compiles in the caller, meaning it works for local variables, parameters, instance fields and instance properties, at least. I haven't checked to see if it works on statics.
In c# 10 you can just do this:
ArgumentNullException.ThrowIfNull(z);
And you will got this error:
System.ArgumentNullException: Value cannot be null. (Parameter 'z')
at System.ArgumentNullException.Throw(String paramName)
at System.ArgumentNullException.ThrowIfNull(Object argument, String paramName)
at ConsoleApp1.SomeClass.Join(String a, String b)
Under the hood, it use the new CallerArgumentExpression attribure.
public class TestClass
{
public TestClass()
{
this.ThrowIfNull(t=>t.Str, t=>t.Test);
//OR
//this.ThrowIfNull(t => t.X)
// .ThrowIfNull(t => t.Test);
}
string Str = "";
public TestClass Test {set;get;}
}
public static class SOExtension
{
public static T ThrowIfNull<T>(this T target, params Expression<Func<T, object>>[] exprs)
{
foreach (var e in exprs)
{
var exp = e.Body as MemberExpression;
if (exp == null)
{
throw new ArgumentException("Argument 'expr' must be of the form x=>x.variableName");
}
var name = exp.Member.Name;
if (e.Compile()(target) == null)
throw new ArgumentNullException(name,"Parameter [" + name + "] can not be null");
}
return target;
}
}
In c# 7 can be done like this:
_ = someParam ?? throw new ArgumentNullException(nameof(someParam));
After release optimisation you will get:
if (someParam == null)
throw new ArgumentNullException(nameof(someParam));
If you aren't opposed to third party utilities, PostSharp provides clean ways to inject such validations. This blog post provides a solution to your problem.
Update: See new Validating-parameters features in PostSharp 3
How about an extension method?
public static void ThrowExceptionIfNull(this object argument, string argumentName)
{
if(argument == null)
throw new ArgumentNullException(argumentName);
}
Then your code at least reads a little more fluently:
someParam.ThrowExceptionIfNull("someParam");
Otherwise, I would agree with the others to split the functionality or use AOP (ie. PostSharp)
Well, the boilerplate is hard to avoid. You could switch to using the Bertrand Meyers' Eiffel programming language and EiffelStudio instead of C# and Visual Studio and start practicing "design by contract™".
Eiffel is fully CLR-compliant these days.
There are a lot of valid solutions already, but here's my take:
using System.Diagnostics;
using System.Reflection;
public SomeConstructor(int? par1, int? par2, string par3)
{
CheckThrowNull(par1, par2, par3);
//rest of constructor code...
}
///<param name="values"> Values must be given in order </param>
public static void CheckThrowNull(params object[] values)
{
StackTrace stackTrace = new StackTrace();
ParameterInfo[] parameters = stackTrace.GetFrame(1).GetMethod().GetParameters(); //get calling method's parameters (or constructor)
if (parameters.Length != values.Length)
{
throw new ArgumentException("Incorrect number of values passed in");
}
for (int i = 0; i < parameters.Length; i++)
{
if (values[i] == null)
{
//value was null, throw exception with corresponding parameter name
throw new ArgumentNullException(parameters[i].Name);
}
}
}
The general idea is that two parallel arrays are established, one of type ParameterInfo, and one containing the values of the parameter. The latter has to passed in because parameter values aren't easily (and I think impossible) obtainable via reflection. To give credit where it is due, I found how to get the calling method here: http://www.csharp-examples.net/reflection-calling-method-name/
Personally, I don't like using System.Diagnosics except for debugging, so I would make a slight modification, having calling code be:
CheckThrowNull(MethodBase.GetCurrentMethod(), par1, par2, par3);
and the method being
CheckThrowNull(MethodBase method, params object[] values)
{
ParameterInfo[] parameters = method.GetParameters();
//rest of code same
}
The down-side is its a little non-extensible and can't easily be made to check if just some of the arguments are null.
I wrote benchmark application with multiple variations of extracting argument name (via anonymous class + reflection / MemberExpression / Func / etc)
Github link to benchmark sources: https://github.com/iXab3r/NullCheckCompetition
I got results, that are showing, that the fastest method is through use of anonymous class.
.NET 40 / X64
Fail (i.e. argument IS null and name extraction method is executed)
FailAnonymousClass 67.87 ns
FailDoubleLambda 643.98 ns
FailLazyAnonymousClass 69.36 ns
FailRawCheck 1.08 ns
FailSingleLambda 643.27 ns
Success (i.e. argument is not null)
SuccessAnonymousClass 6.33 ns
SuccessDoubleLambda 8.48 ns
SuccessLazyAnonymousClass 8.78 ns
SuccessRawCheck 1.08 ns
SuccessSingleLambda 628.28 ns
I think most of the above are ok but none of them are really an improvement to what you already have so I would just go for the KIS, Keep It Simple, and that is what you started with.
It's clean, extremly readable and its fast. The only thing it's a bit long
Update for C# 10 (.NET >= 6):
_person = person.ThrowIfNull();
public static T ThrowIfNull<T>(this T? argument, string? message = default, [CallerArgumentExpression("argument")] string? paramName = default)
{
return argument ?? throw new ArgumentNullException(paramName, message);
}
Reference:
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-10.0/caller-argument-expression
With C# 11 and .NET 6.0 you can do this:
public bool DoSomething(string name)
{
ArgumentNullException.ThrowIfNull(name);
// Do your stuff, name is not null
}
ArgumentNullException.ThrowIfNull Method
It is actually possible to retrieve the argument name from the lambda expression without going through the Expression type. This is how it can be done:
static void SampleMethod(string arg1)
{
ThrowIfNull(() => arg1);
// continue to other normal stuff here...
}
public static void ThrowIfNull<T>(Func<T> lambda)
where T : class
{
if (lambda() == null)
{
throw new ArgumentNullException(lambda.Target.GetType().GetFields()[0].Name);
}
}
Related
void MyMethod(string something, params object[] parameters)
{
foreach (object parameter in parameters)
{
// Get the name of each passed parameter
}
}
For example, if I call the method in the following way, I want to get the names "myFirstParam" and "anotherParam".
string myFirstParam = "some kind of text";
string anotherParam = 42;
MyMethod("test", myFirstParam, anotherParam);
Perhaps reflection is the answer? Perhaps it's just not possible? I am aware of the existance of this question, but that solution won't work here.
(Please do not respond with "This is not a good idea". That is not my question.)
This is totally impossible.
Here are just a few cases where it doesn't even make sense:
MyMethod("abc", new object[5]);
MyMethod("abc", "def");
MyMethod("abc", var1 + var2);
MyMethod("abc", SomeMethod());
MyMethod("abc", b ? a : c);
MyMethod("abc", new object());
MyMethod("abc", null);
In fact, local variable names aren't even compiled into the assembly.
Building on #shingo's answer.
Since C#10, you can get the name of the variable passed using CallerArgumentExpressionAttribute Class.
This is .NET6:
using System.Runtime.CompilerServices;
void F(object arg1, [CallerArgumentExpression("arg1")] string arg1Exp = "?")
=> Console.WriteLine($"{arg1Exp} => {arg1}");
var var1 = "C#10";
var var2 = "_";
var b = var1.Length > 7;
F(var1);
F(new object[5]);
F("def");
F(var1 + var2);
F(SomeMethod());
F(b ? var1 : var2);
F(new object());
F(null);
F(int.Parse(var1.Substring(2)) switch {
>= 10 => "Supported",
_ => "Not supported"
});
int SomeMethod() => 7 + 8;
Output (which seems magical):
var1 => C#10
new object[5] => System.Object[]
"def" => def
var1 + var2 => C#10_
SomeMethod() => 15
b ? var1 : var2 => _
new object() => System.Object
null =>
int.Parse(var1.Substring(2)) switch {
>= 10 => "Supported",
_ => "Not supported"
} => Supported
C# 10 has introduced a new attribute CallerArgumentExpressionAttribute.
Getting names from params parameters is still impossible, but if you have fixed number of parameters (like overload methods), then it's possible.
void MyMethod(object p0,
[CallerArgumentExpression("p0") string p0exp = "p0")
{
Console.WriteLine(p0exp);
}
void MyMethod(object p0, object p1,
[CallerArgumentExpression("p0") string p0exp = "p0",
[CallerArgumentExpression("p1") string p1exp = "p1")
{
}
In addition to SLaks's answer - variable names are not available at run-time at all. The variables are represented by stack slots and are addressed by an index. Thus you can't get this information even for the example you provided, not to mention all these examples SLaks provided. Reflection is no help here. Nothing is.
It is not possible, and I wonder why you would need that.
I RAISE THIS QUESTION FROM THE DEAD!
Check out C# 6.0's new nameof() operator. It allows you to do exactly what you want, and it actually isn't always a bad idea.
A good use case is Argument Exceptions, or INotifyPropertyChanged. (Especially when you get inheritance in the mix)
Example:
interface IFooBar
{
void Foo(object bar);
}
public class FooBar : IFooBar
{
public void Foo(object bar)
{
if(bar == null)
{
//Old and Busted
//throw new ArgumentException("bar");
//The new HOTNESS
throw new ArgumentException(nameof(bar)); // nameof(bar) returns "bar"
}
//....
}
}
Now, if you were rename the parameter 'bar' on the method 'Foo' in the interface IFooBar, your argument exceptions would update accordingly (prevents you from forgetting to change the "bar" string)
Pretty neat actually!
What about this;
void MyMethod(string something, object parameters)
{
RouteValueDictionary dic = HtmlHelper.AnonymousObjectToHtmlAttributes(options);
}
MyMethod("test", new { #myFirstParam=""some kind of text", anotherParam=42);
This has already been implemented in System.Web.MVC.Html InputExtension.
I was inspired and using this technique in my code.
It is very flexible.
Dont bother about "Html" naming in the helper methods. There is nothing to do with html, or html attributes inside the helper method.
It just converts named, anonymous arguments to RouteValueDictionary, a special dictionary having IDictionary<string,object> interface where key holds the argument name and object is the value of the argument.
Using reflection, and #Martin's example of null argument testing:
using System.Reflection;
public SomeMethod(ClassA a, ClassB b, ClassC c)
{
CheckNullParams(MethodBase.GetCurrentMethod(), a, b, c);
// do something here
}
accessing the parameter names:
public void CheckNullParams(MethodBase method, params object[] args)
{
for (var i=0; i < args.Count(); i++)
{
if (args[i] == null)
{
throw new ArgumentNullException(method.GetParameters()[i].Name);
}
}
}
This works with constructors and public methods, but I haven't tested beyond unit tests within VS, so possibly there are some runtime JIT issues (reading through articles referenced above).
EDIT: Just noticed, this is essentially the same as linked answer.
I'm writing an application that runs "things" to a schedule.
Idea being that the database contains assembly, method information and also the parameter values. The timer will come along, reflect the method to be run, add the parameters and then execute the method.
Everything is fine except for the parameters.
So, lets say the method accepts an ENUM of CustomerType where CustomerType has two values of CustomerType.Master and CustomerType.Associate.
EDIT
I don't know the type of parameter that will be getting passed in. ENUM used as an example
END OF EDIT
We want to run Method "X" and pass in parameter "CustomerType.Master". In the database, there will be a varchar entry of "CustomerType.Master".
How do I convert the string "CustomerType.Master" into a type of CustomerType with a value of "Master" generically?
Thanks in advance,
Jim
OK, the scope of the question shifted but my original observation and objection to some other solutions still stands.
I think you don't/can't want to use 'generics' here. You don't know the type ahead of time, and since you will need to create the type, there is no need to use a generic implementation because MethodBase.Invoke takes an array of Object.
This code assumes you are instantiating the target from database field. If not just adjust accordingly.
Of course this is not all encompassing and has no useful exception handling, but it will allow you to dynamically execute arbitrary methods on an arbitrary type with arbitrary parameters values all coming from string values in a row.
NOTE: there are many many many scenarios in which this simple executor will not work. You will need to ensure that you engineer your dynamic methods to cooperate with whatever strategy you do end up deciding to use.
using System;
using System.ComponentModel;
using System.Drawing;
using System.Globalization;
using System.Reflection;
using NUnit.Framework;
namespace DynamicMethodInvocation
{
[TestFixture]
public class Tests
{
[Test]
public void Test()
{
// from your database
string assemblyQualifiedTypeName = "DynamicMethodInvocation.TestType, DynamicMethodInvocation";
string methodName = "DoSomething";
// this is how you would get the strings to put in your database
string enumString = Executor.ConvertToString(typeof(AttributeTargets), AttributeTargets.Assembly);
string colorString = Executor.ConvertToString(typeof(Color), Color.Red);
string stringString = "Hmm... String?";
object result = Executor.ExecuteMethod(assemblyQualifiedTypeName, methodName,
new[] { enumString, colorString, stringString });
Assert.IsInstanceOf<bool>(result);
Assert.IsTrue((bool)result);
}
}
public class TestType
{
public bool DoSomething(AttributeTargets #enum, Color color, string #string)
{
return true;
}
}
public class Executor
{
public static object ExecuteMethod(string assemblyQualifiedTypeName, string methodName,
string[] parameterValueStrings)
{
Type targetType = Type.GetType(assemblyQualifiedTypeName);
MethodBase method = targetType.GetMethod(methodName);
ParameterInfo[] pInfo = method.GetParameters();
var parameterValues = new object[parameterValueStrings.Length];
for (int i = 0; i < pInfo.Length; i++)
{
parameterValues[i] = ConvertFromString(pInfo[i].ParameterType, parameterValueStrings[i]);
}
// assumes you are instantiating the target from db and that it has a parameterless constructor
// otherwise, if the target is already known to you and instantiated, just use it...
return method.Invoke(Activator.CreateInstance(targetType), parameterValues);
}
public static string ConvertToString(Type type, object val)
{
if (val is string)
{
return (string) val;
}
TypeConverter tc = TypeDescriptor.GetConverter(type);
if (tc == null)
{
throw new Exception(type.Name + " is not convertable to string");
}
return tc.ConvertToString(null, CultureInfo.InvariantCulture, val);
}
public static object ConvertFromString(Type type, string val)
{
TypeConverter tc = TypeDescriptor.GetConverter(type);
if (tc == null)
{
throw new Exception(type.Name + " is not convertable.");
}
if (!tc.IsValid(val))
{
throw new Exception(type.Name + " is not convertable from " + val);
}
return tc.ConvertFrom(null, CultureInfo.InvariantCulture, val);
}
}
}
I would think you have 2 major options:
Store the type name along with the parameter value and use that to cast things using Type.GetType(string) to resolve the type in question.
Standardize all the methods to be called this way to accept an array of strings, and expect the methods to do any necessary casting.
I know you've stated that you're not doing option 1, but it would help things from the standpoint of calling the functions.
Option 2 is the far more 'generic' way to handle the situation, assuming all values can be represented by and cast/converted from strings to the appropriate type. Of course, that only helps if you actually have control over the definition of the methods being called.
Below is a useful extension method I use in .NET 3.5.
With this extension method available, your code could look like this:
var valueInDb = GetStringFromDb().Replace("CustomerType.", string.Empty);
var value = valueInDb.ToEnum(CustomerType.Associate);
By supplying the default value in the parameter, the compiler will know which Enum you want your string to be turned into. It will try to find your text in the Enum. If it doesn't it will return the default value.
Here is the extension method: (this version also does partial matches, so even "M" would work nicely!)
public static T ToEnum<T>(this string input, T defaultValue)
{
var enumType = typeof (T);
if (!enumType.IsEnum)
{
throw new ArgumentException(enumType + " is not an enumeration.");
}
// abort if no value given
if (string.IsNullOrEmpty(input))
{
return defaultValue;
}
// see if the text is valid for this enumeration (case sensitive)
var names = Enum.GetNames(enumType);
if (Array.IndexOf(names, input) != -1)
{
// case insensitive...
return (T) Enum.Parse(enumType, input, true);
}
// do partial matching...
var match = names.Where(name => name.StartsWith(input, StringComparison.InvariantCultureIgnoreCase)).FirstOrDefault();
if(match != null)
{
return (T) Enum.Parse(enumType, match);
}
// didn't find one
return defaultValue;
}
I still don't fully understand your question... however, you say "Everything is fine except for the parameters."
I'll assume "CustomerType" the name of a property on your object, and "Master" is the string value you want to put in that property.
Here is (another) extension method that may help.
Once you have your new object and the value and property name from the database field, you could use this:
// string newValue = "Master";
// string propertyName = "CustomerType";
myNewObject.SetPropertyValue(propertyName, newValue)
Method:
/// <summary>Set the value of this property, as an object.</summary>
public static void SetPropertyValue(this object obj,
string propertyName,
object objValue)
{
const BindingFlags attr = BindingFlags.Public | BindingFlags.Instance;
var type = obj.GetType();
var property = type.GetProperty(propertyName, attr);
if(property == null) return;
var propertyType = property.PropertyType;
if (propertyType.IsValueType && objValue == null)
{
// This works for most value types, but not custom ones
objValue = 0;
}
// need to change some types... e.g. value may come in as a string...
var realValue = Convert.ChangeType(objValue, propertyType);
property.SetValue(obj, realValue, null);
}
If you are using .NET 4 you can do the following.
var result = default(CustomerType);
if (!Enum.TryParse("Master", out result))
{
// handle error
}
Note: This question was asked before the introduction of the .? operator in C# 6 / Visual Studio 2015.
We've all been there, we have some deep property like cake.frosting.berries.loader that we need to check if it's null so there's no exception. The way to do is is to use a short-circuiting if statement
if (cake != null && cake.frosting != null && cake.frosting.berries != null) ...
This is not exactly elegant, and there should perhaps be an easier way to check the entire chain and see if it comes up against a null variable/property.
Is it possible using some extension method or would it be a language feature, or is it just a bad idea?
We have considered adding a new operation "?." to the language that has the semantics you want. (And it has been added now; see below.) That is, you'd say
cake?.frosting?.berries?.loader
and the compiler would generate all the short-circuiting checks for you.
It didn't make the bar for C# 4. Perhaps for a hypothetical future version of the language.
Update (2014):
The ?. operator is now planned for the next Roslyn compiler release. Note that there is still some debate over the exact syntactic and semantic analysis of the operator.
Update (July 2015): Visual Studio 2015 has been released and ships with a C# compiler that supports the null-conditional operators ?. and ?[].
I got inspired by this question to try and find out how this kind of deep null checking can be done with an easier / prettier syntax using expression trees. While I do agree with the answers stating that it might be a bad design if you often need to access instances deep in the hierarchy, I also do think that in some cases, such as data presentation, it can be very useful.
So I created an extension method, that will allow you to write:
var berries = cake.IfNotNull(c => c.Frosting.Berries);
This will return the Berries if no part of the expression is null. If null is encountered, null is returned. There are some caveats though, in the current version it will only work with simple member access, and it only works on .NET Framework 4, because it uses the MemberExpression.Update method, which is new in v4. This is the code for the IfNotNull extension method:
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
namespace dr.IfNotNullOperator.PoC
{
public static class ObjectExtensions
{
public static TResult IfNotNull<TArg,TResult>(this TArg arg, Expression<Func<TArg,TResult>> expression)
{
if (expression == null)
throw new ArgumentNullException("expression");
if (ReferenceEquals(arg, null))
return default(TResult);
var stack = new Stack<MemberExpression>();
var expr = expression.Body as MemberExpression;
while(expr != null)
{
stack.Push(expr);
expr = expr.Expression as MemberExpression;
}
if (stack.Count == 0 || !(stack.Peek().Expression is ParameterExpression))
throw new ApplicationException(String.Format("The expression '{0}' contains unsupported constructs.",
expression));
object a = arg;
while(stack.Count > 0)
{
expr = stack.Pop();
var p = expr.Expression as ParameterExpression;
if (p == null)
{
p = Expression.Parameter(a.GetType(), "x");
expr = expr.Update(p);
}
var lambda = Expression.Lambda(expr, p);
Delegate t = lambda.Compile();
a = t.DynamicInvoke(a);
if (ReferenceEquals(a, null))
return default(TResult);
}
return (TResult)a;
}
}
}
It works by examining the expression tree representing your expression, and evaluating the parts one after the other; each time checking that the result is not null.
I am sure this could be extended so that other expressions than MemberExpression is supported. Consider this as proof-of-concept code, and please keep in mind that there will be a performance penalty by using it (which will probably not matter in many cases, but don't use it in a tight loop :-) )
I've found this extension to be quite useful for deep nesting scenarios.
public static R Coal<T, R>(this T obj, Func<T, R> f)
where T : class
{
return obj != null ? f(obj) : default(R);
}
It's an idea I derrived from the null coalescing operator in C# and T-SQL. The nice thing is that the return type is always the return type of the inner property.
That way you can do this:
var berries = cake.Coal(x => x.frosting).Coal(x => x.berries);
...or a slight variation of the above:
var berries = cake.Coal(x => x.frosting, x => x.berries);
It's not the best syntax I know, but it does work.
Besides violating the Law of Demeter, as Mehrdad Afshari has already pointed out, it seems to me you need "deep null checking" for decision logic.
This is most often the case when you want to replace empty objects with default values. In this case you should consider implementing the Null Object Pattern. It acts as a stand-in for a real object, providing default values and "non-action" methods.
Update: Starting with Visual Studio 2015, the C# compiler (language version 6) now recognizes the ?. operator, which makes "deep null checking" a breeze. See this answer for details.
Apart from re-designing your code, like
this deleted answer suggested,
another (albeit terrible) option would be to use a try…catch block to see if a NullReferenceException occurs sometime during that deep property lookup.
try
{
var x = cake.frosting.berries.loader;
...
}
catch (NullReferenceException ex)
{
// either one of cake, frosting, or berries was null
...
}
I personally wouldn't do this for the following reasons:
It doesn't look nice.
It uses exception handling, which should target exceptional situations and not something that you expect to happen often during the normal course of operation.
NullReferenceExceptions should probably never be caught explicitly. (See this question.)
So is it possible using some extension method or would it be a language feature, [...]
This would almost certainly have to be a language feature (which is available in C# 6 in the form of the .? and ?[] operators), unless C# already had more sophisticated lazy evaluation, or unless you want to use reflection (which probably also isn't a good idea for reasons of performance and type-safety).
Since there's no way to simply pass cake.frosting.berries.loader to a function (it would be evaluated and throw a null reference exception), you would have to implement a general look-up method in the following way: It takes in an objects and the names of properties to look up:
static object LookupProperty( object startingPoint, params string[] lookupChain )
{
// 1. if 'startingPoint' is null, return null, or throw an exception.
// 2. recursively look up one property/field after the other from 'lookupChain',
// using reflection.
// 3. if one lookup is not possible, return null, or throw an exception.
// 3. return the last property/field's value.
}
...
var x = LookupProperty( cake, "frosting", "berries", "loader" );
(Note: code edited.)
You quickly see several problems with such an approach. First, you don't get any type safety and possible boxing of property values of a simple type. Second, you can either return null if something goes wrong, and you will have to check for this in your calling function, or you throw an exception, and you're back to where you started. Third, it might be slow. Fourth, it looks uglier than what you started with.
[...], or is it just a bad idea?
I'd either stay with:
if (cake != null && cake.frosting != null && ...) ...
or go with the above answer by Mehrdad Afshari.
P.S.: Back when I wrote this answer, I obviously didn't consider expression trees for lambda functions; see e.g. #driis' answer for a solution in this direction. It's also based on a kind of reflection and thus might not perform quite as well as a simpler solution (if (… != null & … != null) …), but it may be judged nicer from a syntax point-of-view.
While driis' answer is interesting, I think it's a bit too expensive performance wise. Rather than compiling many delegates, I'd prefer to compile one lambda per property path, cache it and then reinvoke it many types.
NullCoalesce below does just that, it returns a new lambda expression with null checks and a return of default(TResult) in case any path is null.
Example:
NullCoalesce((Process p) => p.StartInfo.FileName)
Will return an expression
(Process p) => (p != null && p.StartInfo != null ? p.StartInfo.FileName : default(string));
Code:
static void Main(string[] args)
{
var converted = NullCoalesce((MethodInfo p) => p.DeclaringType.Assembly.Evidence.Locked);
var converted2 = NullCoalesce((string[] s) => s.Length);
}
private static Expression<Func<TSource, TResult>> NullCoalesce<TSource, TResult>(Expression<Func<TSource, TResult>> lambdaExpression)
{
var test = GetTest(lambdaExpression.Body);
if (test != null)
{
return Expression.Lambda<Func<TSource, TResult>>(
Expression.Condition(
test,
lambdaExpression.Body,
Expression.Default(
typeof(TResult)
)
),
lambdaExpression.Parameters
);
}
return lambdaExpression;
}
private static Expression GetTest(Expression expression)
{
Expression container;
switch (expression.NodeType)
{
case ExpressionType.ArrayLength:
container = ((UnaryExpression)expression).Operand;
break;
case ExpressionType.MemberAccess:
if ((container = ((MemberExpression)expression).Expression) == null)
{
return null;
}
break;
default:
return null;
}
var baseTest = GetTest(container);
if (!container.Type.IsValueType)
{
var containerNotNull = Expression.NotEqual(
container,
Expression.Default(
container.Type
)
);
return (baseTest == null ?
containerNotNull :
Expression.AndAlso(
baseTest,
containerNotNull
)
);
}
return baseTest;
}
One option is to use the Null Object Patten, so instead of having null when you don’t have a cake, you have a NullCake that returns a NullFosting etc. Sorry I am not very good at explaining this but other people are, see
An example of the Null Object Patten usage
The wikipedai write up on the Null Object Patten
I too have often wished for a simpler syntax! It gets especially ugly when you have method-return-values that might be null, because then you need extra variables (for example: cake.frosting.flavors.FirstOrDefault().loader)
However, here's a pretty decent alternative that I use: create an Null-Safe-Chain helper method. I realize that this is pretty similar to #John's answer above (with the Coal extension method) but I find it's more straightforward and less typing. Here's what it looks like:
var loader = NullSafe.Chain(cake, c=>c.frosting, f=>f.berries, b=>b.loader);
Here's the implementation:
public static TResult Chain<TA,TB,TC,TResult>(TA a, Func<TA,TB> b, Func<TB,TC> c, Func<TC,TResult> r)
where TA:class where TB:class where TC:class {
if (a == null) return default(TResult);
var B = b(a);
if (B == null) return default(TResult);
var C = c(B);
if (C == null) return default(TResult);
return r(C);
}
I also created several overloads (with 2 to 6 parameters), as well as overloads that allow the chain to end with a value-type or default. This works really well for me!
There is Maybe codeplex project that Implements
Maybe or IfNotNull using lambdas for deep expressions in C#
Example of use:
int? CityId= employee.Maybe(e=>e.Person.Address.City);
The link was suggested in a similar question How to check for nulls in a deep lambda expression?
As suggested in John Leidegren's answer, one approach to work-around this is to use extension methods and delegates. Using them could look something like this:
int? numberOfBerries = cake
.NullOr(c => c.Frosting)
.NullOr(f => f.Berries)
.NullOr(b => b.Count());
The implementation is messy because you need to get it to work for value types, reference types and nullable value types. You can find a complete implementation in Timwi's answer to What is the proper way to check for null values?.
Or you may use reflection :)
Reflection function:
public Object GetPropValue(String name, Object obj)
{
foreach (String part in name.Split('.'))
{
if (obj == null) { return null; }
Type type = obj.GetType();
PropertyInfo info = type.GetProperty(part);
if (info == null) { return null; }
obj = info.GetValue(obj, null);
}
return obj;
}
Usage:
object test1 = GetPropValue("PropertyA.PropertyB.PropertyC",obj);
My Case(return DBNull.Value instead of null in reflection function):
cmd.Parameters.AddWithValue("CustomerContactEmail", GetPropValue("AccountingCustomerParty.Party.Contact.ElectronicMail.Value", eInvoiceType));
Try this code:
/// <summary>
/// check deep property
/// </summary>
/// <param name="obj">instance</param>
/// <param name="property">deep property not include instance name example "A.B.C.D.E"</param>
/// <returns>if null return true else return false</returns>
public static bool IsNull(this object obj, string property)
{
if (string.IsNullOrEmpty(property) || string.IsNullOrEmpty(property.Trim())) throw new Exception("Parameter : property is empty");
if (obj != null)
{
string[] deep = property.Split('.');
object instance = obj;
Type objType = instance.GetType();
PropertyInfo propertyInfo;
foreach (string p in deep)
{
propertyInfo = objType.GetProperty(p);
if (propertyInfo == null) throw new Exception("No property : " + p);
instance = propertyInfo.GetValue(instance, null);
if (instance != null)
objType = instance.GetType();
else
return true;
}
return false;
}
else
return true;
}
I posted this last night and then a friend pointed me to this question. Hope it helps. You can then do something like this:
var color = Dis.OrDat<string>(() => cake.frosting.berries.color, "blue");
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;
namespace DeepNullCoalescence
{
public static class Dis
{
public static T OrDat<T>(Expression<Func><T>> expr, T dat)
{
try
{
var func = expr.Compile();
var result = func.Invoke();
return result ?? dat; //now we can coalesce
}
catch (NullReferenceException)
{
return dat;
}
}
}
}
Read the full blog post here.
The same friend also suggested that you watch this.
I slightly modified the code from here to make it work for the question asked:
public static class GetValueOrDefaultExtension
{
public static TResult GetValueOrDefault<TSource, TResult>(this TSource source, Func<TSource, TResult> selector)
{
try { return selector(source); }
catch { return default(TResult); }
}
}
And yes, this is probably not the optimal solution due to try/catch performance implications but it works :>
Usage:
var val = cake.GetValueOrDefault(x => x.frosting.berries.loader);
Where you need to achieve this, do this:
Usage
Color color = someOrder.ComplexGet(x => x.Customer.LastOrder.Product.Color);
or
Color color = Complex.Get(() => someOrder.Customer.LastOrder.Product.Color);
Helper class implementation
public static class Complex
{
public static T1 ComplexGet<T1, T2>(this T2 root, Func<T2, T1> func)
{
return Get(() => func(root));
}
public static T Get<T>(Func<T> func)
{
try
{
return func();
}
catch (Exception)
{
return default(T);
}
}
}
I like approach taken by Objective-C:
"The Objective-C language takes another approach to this problem and does not invoke methods on nil but instead returns nil for all such invocations."
if (cake.frosting.berries != null)
{
var str = cake.frosting.berries...;
}
Is it possible to evaluate the following in C# at runtime
I have a class that contains 3 properties (Field,Operator,Value)
rule.Field;
rule.Operator;
rule.Value;
this is my rule class...
Now I have a loop
foreach(item in items)
{
// here I want to create a dynamic expression to evaluate at runtime
// something like
if (item.[rule.field] [rule.operator] [rule.value])
{ do work }
}
I just don't know the syntax, or if its possible in C#, I know in JS its possible but that's not a compiled language.
Update
Essentially I want a way to eval(stringCode) or a better more supported way.
No, C# doesn't support anything like this directly.
The closest options are:
Create a full valid C# program and dynamically compile it with CSharpCodeProvider.
Build an expression tree, compile and execute it
Perform the evaluation yourself (this may actually be easiest, depending on your operators etc)
Disclaimer: I'm the owner of the project Eval Expression.NET
This library is close to being the JS Eval equivalent. You can almost evaluate and compile all the C# language.
Here is a simple example using your question, but the library goes way beyond this simple scenario.
int field = 2;
int value = 1;
string binaryOperator = ">";
string formula = "x " + binaryOperator + " y";
// For single evaluation
var value1 = Eval.Execute<bool>(formula, new { x = field, y = value });
// For many evaluation
var compiled = Eval.Compile<Func<int, int, bool>>(formula, "x", "y");
var value2 = compiled(field, value);
EDIT Answer comment:
Proprietary library to do simple evaluation? No, thanks
This library does not support only simple evaluation but almost all the C# languages. Allowing you to add dynamically a method, use async, linq, loop, etc., which is more than "to do simple evaluation"
The closest options solution provided by Jon Skeet are great but will surely take several days of development and testing to support all cases, depending on the operators. Surely this library helps some developers, but in some other scenarios, like yours, it could be done without it.
I'm not entirely sure what you are saying. Can you try clarifying it a bit?
Are you wanting to to take a string expression and evaluate it at runtime in C#? If so the answer is no. C# does not support such types of dynamic evaluation.
You'd have to either use the CodeDOM libraries or create an Expression tree, compile it, and execute it. I think building up the expression tree is the best option.
Of course you could put in a switch statement on your operator, which is not bad because there is a limited number of operators you could use anyways.
Here's a way to do this with expression trees (written in LINQPad):
void Main()
{
var programmers = new List<Programmer>{
new Programmer { Name = "Turing", Number = Math.E},
new Programmer { Name = "Babbage", Number = Math.PI},
new Programmer { Name = "Lovelace", Number = Math.E}};
var rule0 = new Rule<string>() { Field = "Name", Operator = BinaryExpression.Equal, Value = "Turing" };
var rule1 = new Rule<double>() { Field = "Number", Operator = BinaryExpression.GreaterThan, Value = 2.719 };
var matched0 = RunRule<Programmer, string>(programmers, rule0);
matched0.Dump();
var matched1 = RunRule<Programmer, double>(programmers, rule1);
matched1.Dump();
var matchedBoth = matched0.Intersect(matched1);
matchedBoth.Dump();
var matchedEither = matched0.Union(matched1);
matchedEither.Dump();
}
public IEnumerable<T> RunRule<T, V>(IEnumerable<T> foos, Rule<V> rule) {
var fieldParam = Expression.Parameter(typeof(T), "f");
var fieldProp = Expression.Property (fieldParam, rule.Field);
var valueParam = Expression.Parameter(typeof(V), "v");
BinaryExpression binaryExpr = rule.Operator(fieldProp, valueParam);
var lambda = Expression.Lambda<Func<T, V, bool>>(binaryExpr, fieldParam, valueParam);
var func = lambda.Compile();
foreach(var foo in foos) {
var result = func(foo, rule.Value);
if(result)
yield return foo;
}
}
public class Rule<T> {
public string Field { get; set; }
public Func<Expression, Expression, BinaryExpression> Operator { get; set; }
public T Value { get; set; }
}
public class Programmer {
public string Name { get; set; }
public double Number { get; set; }
}
A better design for you would be for your rule to apply the test itself (or to an arbitrary value)
By doing this with Func instances you will get the most flexibility, like so:
IEnumerable<Func<T,bool> tests; // defined somehow at runtime
foreach (var item in items)
{
foreach (var test in tests)
{
if (test(item))
{
//do work with item
}
}
}
then your specific test would be something like this for strong type checking at compile time:
public Func<T,bool> FooEqualsX<T,V>(V x)
{
return t => EqualityComparer<V>.Default.Equals(t.Foo, x);
}
For a reflective form
public Func<T,bool> MakeTest<T,V>(string name, string op, V value)
{
Func<T,V> getter;
var f = typeof(T).GetField(name);
if (f != null)
{
if (!typeof(V).IsAssignableFrom(f.FieldType))
throw new ArgumentException(name +" incompatible with "+ typeof(V));
getter= x => (V)f.GetValue(x);
}
else
{
var p = typeof(T).GetProperty(name);
if (p == null)
throw new ArgumentException("No "+ name +" on "+ typeof(T));
if (!typeof(V).IsAssignableFrom(p.PropertyType))
throw new ArgumentException(name +" incompatible with "+ typeof(V));
getter= x => (V)p.GetValue(x, null);
}
switch (op)
{
case "==":
return t => EqualityComparer<V>.Default.Equals(getter(t), value);
case "!=":
return t => !EqualityComparer<V>.Default.Equals(getter(t), value);
case ">":
return t => Comparer<V>.Default.Compare(getter(t), value) > 0;
// fill in the banks as you need to
default:
throw new ArgumentException("unrecognised operator '"+ op +"'");
}
}
If you wanted to be really introspective and handle any literal without knowing at compile time you could use the CSharpCodeProvider to compile a function assuming something like:
public static bool Check(T t)
{
// your code inserted here
}
This is of course a massive security hole so whoever can supply code for this must be fully trusted. Here is a somewhat limited implementation for your specific needs (no sanity checking at all)
private Func<T,bool> Make<T>(string name, string op, string value)
{
var foo = new Microsoft.CSharp.CSharpCodeProvider()
.CompileAssemblyFromSource(
new CompilerParameters(),
new[] { "public class Foo { public static bool Eval("+
typeof(T).FullName +" t) { return t."+
name +" "+ op +" "+ value
+"; } }" }).CompiledAssembly.GetType("Foo");
return t => (bool)foo.InvokeMember("Eval",
BindingFlags.Static | BindingFlags.Public | BindingFlags.InvokeMethod ,
null, null, new object[] { t });
}
// use like so:
var f = Make<string>("Length", ">", "2");
For this to work with arbitrary types you would have to do a bit more reflection to find the target assembly for the type to reference it in the compiler parameters.
private bool Eval(object item, string name, string op, string value)
{
var foo = new Microsoft.CSharp.CSharpCodeProvider()
.CompileAssemblyFromSource(
new CompilerParameters(),
new[] { "public class Foo { public static bool Eval("+
item.GetType().FullName +" t) "+
"{ return t."+ name +" "+ op +" "+ value +"; } }"
}).CompiledAssembly.GetType("Foo");
return (bool)foo.InvokeMember("Eval",
BindingFlags.Static | BindingFlags.Public | BindingFlags.InvokeMethod ,
null, null, new object[] { item });
}
All the above code is simply a proof of concept, it lacks sanity checking and has serious performance issues.
If you wanted to be even fancier you could use Reflection.Emit with DynamicMethod instances to do it (using proper operators rather than the default comparer instances) but this would require complex handling for types with overridden operators.
By making your check code highly generic you may include more tests in future as you need to. Essentially isolate the part of your code that cares only about a function from t -> true/false from the code that supplies these functions.
CSharpCodeProvider; switch statements that pick the proper different "operators"; the DLR... they are all ways you could do this; but they seem weird solutions to me.
How about just using delegates?
Assuming your Field and Value are numbers, declare something like this:
delegate bool MyOperationDelegate(decimal left, decimal right);
...
class Rule {
decimal Field;
decimal Value;
MyOperationDelegate Operator;
}
Now you can define your 'rule' as, for example, a bunch of lambdas:
Rule rule1 = new Rule;
rule1.Operation = (decimal l, decimal r) => { return l > r; };
rule1.Field = ...
You can make arrays of rules and apply them whichever way you wish.
IEnumerable<Rule> items = ...;
foreach(item in items)
{
if (item.Operator(item.Field, item.Value))
{ /* do work */ }
}
If Field and Values are not numbers, or the type depends on the specific rule, you can use object instead of decimal, and with a little bit of casting you can make it all work.
That's not a final design; it's just to give you some ideas (for example, you would likely have the class evaluate the delegate on its own via a Check() method or something).
You can retrieve the field by reflection. And then implement the operators as methods and uses reflection or some types of enum-delegate mapping to call the operators. The operators should have at least 2 parameters, the input value and the value you are using to test against with.
While it is true that you probably won't find an elegant way to evaluate full C# code on the fly without the use of dynamically compiling code (which is never pretty), you can almost certainly get your rules evaluated in short order using either the DLR (IronPython, IronRuby, etc) or an expression evaluator library that parses and executes a custom syntax. There is one, Script.NET, that provides a very similar syntax to C#.
Take a look here:Evaluating Expressions a Runtime in .NET(C#)
If you have the time / inclination to learn a little Python, then IronPython and the DLR will solve all your issues:
Extending your App with IronPython
when validating methods' input, I used to check if the argument is null, and if so I throw an ArgumentNullException. I do this for each and every argument in the list so I end up with code like this:
public User CreateUser(string userName, string password,
string Email, string emailAlerts,
string channelDescription)
{
if (string.IsNullOrEmpty(userName))
throw new ArgumentNullException("Username can't be null");
if (string.IsNullOrEmpty(Email))
throw new ArgumentNullException("Email can't be null");
//etc, etc, etc
}
Is this OK? Why should I do this? Would it be ok if I simply group all the checks and return a null value instead of throwing the exception? What is the best practice to address this situation?
PS: I want to change this, because with long methods, it gets very tedious to do so. Ideas?
Make an ArgChecker class with something like this
ArgChecker.ThrowOnStringNullOrEmpty(userName, "Username");
where ThrowOnStringNullOrEmpty is
public static void ThrowOnStringNullOrEmpty(string arg, string name)
{
if (string.IsNullOrEmpty(arg))
throw new ArgumentNullException(name + " can't be null");
}
You could also try to process a list of arguments using a params arg, like:
public static void ThrowOnAnyStringNullOrEmpty(params string[] argAndNames)
{
for (int i = 0; i < argAndName.Length; i+=2) {
ThrowOnStringNullOrEmpty(argAndNames[i], argAndNames[i+1]);
}
}
and call like this
ArgChecker.ThrowOnAnyStringNullOrEmpty(userName, "Username", Email, "email");
An approach which I use and I may have picked up from the NHibernate source is to create a static class Guard, used as follows:
public void Foo(object arg1, string arg2, int arg3)
{
Guard.ArgumentNotNull(arg1, "arg1");
Guard.ArgumentNotNullOrEmpty(arg2, "arg2");
Guard.ArgumentGreaterThan(arg3, "arg3", 0);
//etc.
}
public static class Guard
{
public static void ArgumentNotNull(object argument, string parameterName)
{
if (parameterName == null)
throw new ArgumentNullException("parameterName");
if (argument == null)
throw new ArgumentNullException(parameterName);
}
//etc.
}
This cuts down a lot of the chaff at the beginning of methods and it performs well.
You should think about the method, what it needs to do and with what data. If null values represent actual failure conditions, use exceptions. If null values are acceptable, accept them.
Think about the principles from design by contract, specifically what the preconditions to your function are, and standardize a way to enforce them (which Matt and Lou both suggest in their answers so I don't need to go into detail).
Another important thing to consider is the size of your method signatures. If you have a lot of parameters for your methods, this probably means you have bad abstractions. You can cut down on the number of parameter checks you have to make if you group parameters together in collection objects and use those objects as parameters. You can move the parameter checking to those objects instead of having to check them in every function that uses them.
So instead of passing ten related parameters to every function, figure out the few that are used in every function and package them up in an object, and include in that object methods to validate the parameters. This has the added advantage of being easy to change should the rules regarding one parameter need to be updated.
And for the C# 3.0 developers amongst us a great way to encapsulate this null checking is inside an extension method.
public void Foo(string arg1, int? arg2)
{
arg1.ThrowOnNull();
arg2.ThrowOnNull();
}
public static class extensions
{
public static void ThrowOnNull<T>(this T argument) where T : class
{
if(argument == null) throw new ArgumentNullException();
}
}
And if you wanted you could always overload that to take an argument name.
A small improvement to Lou's answer would be to use a hashtable instead, it means it checks objects aswell as just strings. Also just nicer to populate and handle in the method:
public static class ParameterChecker
{
public static void CheckForNull(Hashtable parameters)
{
foreach (DictionaryEntry param in parameters)
{
if (param.Value == null || string.IsNullOrEmpty(param.Value as string))
{
throw new ArgumentNullException(param.Key.ToString());
}
}
}
}
As you would use like:
public User CreateUser(string userName, string password, string Email, string emailAlerts, string channelDescription)
{
var parameters = new Hashtable();
parameters.Add("Username", userName);
parameters.Add("Password", password);
parameters.Add("EmailAlerts", emailAlerts);
parameters.Add("ChannelDescription", channelDescription);
ParameterChecker.CheckForNull(parameters);
// etc etc
}
I would stick with your original approach, except for just passing in the parameter name. The reason is that once you start writing those helper procedures it becomes an issue when everyone starts using different conventions for how they write the helper procedures. When someone looks over your code, they now have to check to make sure you've written the helper procedure correctly when debugging your code.
Keep checking each argument separately, though youor fingers grow weary from typing Grasshopper :) Your followers will bless you when they get the unexpected ArgumentException and are saved from a debugging run just to determine which argument failed.
My first advice to you is get ReSharper. It will tell you when there is a problem of possible null values, and when there is no need to check for them, and with the click of a mouse will add checking. Having said that...
You don't have to check for int or bool, which cannot be null.
Strings can be checked with string.IsNullOrEmpty()...
If you still decide that you want to check each and every parameter, you can either use the Command design pattern, and reflection, but your code will be unnecessarily clunky, or use the following and call it for each method:
private myType myMethod(string param1, int param2, byte[] param3)
{
CheckParameters("myMethod", {param1, param2, param3});
// rest of code...
And in your utility class put this:
///<summary>Validates method parameters</summary>
///... rest of documentation
public void CheckParameters(string methodName, List<Object> parameterValues)
{
if ( string.IsNullOrEmpty(methodName) )
throw new ArgumentException("Fire the programmer! Missing method name", "methodName"));
Type t = typeof(MyClass);
MethodInfo method = t.GetMethod(methodName);
if ( method == null )
throw new ArgumentException("Fire the programmer! Wrong method name", "methodName"));
List<ParameterInfo> params = method.GetParameters();
if ( params == null || params.Count != parameterValues.Count )
throw new ArgumentException("Fire the programmer! Wrong list of parameters. Should have " + params.Count + " parameters", "parameterValues"));
for (int i = 0; i < params.Count; i++ )
{
ParamInfo param = params[i];
if ( param.Type != typeof(parameterValues[i]) )
throw new ArgumentException("Fire the programmer! Wrong order of parameters. Error in param " + param.Name, "parameterValues"));
if ( parameterValues[i] == null )
throw new ArgumentException(param.Name + " cannot be null");
}
} // enjoy
Use an AggregateException (which is meant to contain multiple exceptions) with a list of multiple ArgumentNullException instances. Don't forget to also take advantage of the parameterName argument of ArgumentNullException which works great with nameof():
var exceptions = new List<Exceptions>();
if (firstArgument == null)
exceptions.Add(new ArgumentNullException(nameof(firstArgument), "Some optional message"));
if (secondArgument == null)
exceptions.Add(new ArgumentNullException(nameof(secondArgument), "Another optional message"));
if (exceptions.Count > 0)
throw new AggregateException(exceptions);