Альтернативным подходом является метод расширения:
public static void ThrowIfNull<T>(this T obj, string parameterName) where T : class
{
if(obj == null) throw new ArgumentNullException(parameterName);
}
затем позвоните:
foo.ThrowIfNull("foo");
bar.ThrowIfNull("bar");
T : class
предотвращает нас случайно бокса и т. Д.
Re AOP; У Джона Скита есть образец для чего-то похожего здесь - но охватывающего один метод / параметр.
Вот воспроизводимый аспект; обратите внимание, что этот аспект охватывает только 1 аргумент за раз и зависит от метода, но в целом я бы сказал, что это вполне разумно ... однако, вы, вероятно, можете изменить его.
using System;
using System.Reflection;
using PostSharp.Laos;
namespace IteratorBlocks
{
[Serializable]
class NullArgumentAspect : OnMethodBoundaryAspect
{
string name;
int position;
public NullArgumentAspect(string name)
{
this.name = name;
}
public override void CompileTimeInitialize(MethodBase method)
{
base.CompileTimeInitialize(method);
ParameterInfo[] parameters = method.GetParameters();
for (int index = 0; index < parameters.Length; index++)
{
if (parameters[index].Name == name)
{
position = index;
return;
}
}
throw new ArgumentException("No parameter with name " + name);
}
public override void OnEntry(MethodExecutionEventArgs eventArgs)
{
if (eventArgs.GetArguments()[position] == null)
{
throw new ArgumentNullException(name);
}
}
}
}