ArgumentNullException - 如何简化? [英] ArgumentNullException - how to simplify?

查看:96
本文介绍了ArgumentNullException - 如何简化?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经注意到这个代码庄稼了很多在我的构造函数:

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),
    ... });



...这并不能真正帮助精简代码。 Tuple.Create()而不是KVPs不起作用,因为元组的茶多酚不是协变的(即使IEnumerable的的GTP是)。 ?任何想法

... 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?

推荐答案

Upticks对于大多数的你们;你的答案促使我终于赶到,其中纳入星星点点的解决方案,但最终是所有的人都不同。

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.

我创建了一个情侣的工作静态方法一种特定形式的lambda表达式(修改 - 小的变化;这些方法不能通用,否则将要求所有表达式,返回同一类型的函数功能是罚款代替,随着的GetName一个额外条件方法来解开演员):

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);

这降低了样板一条线,没有第三方工具。的ExpressionReader,并且因此异常产生的方法,在形式()=> VARIABLENAME该编译的呼叫者,这意味着它为局部变量,参数,实例字段和实例属性,至少任拉姆达工作。我没有检查,看看它是否适用于静。

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.

这篇关于ArgumentNullException - 如何简化?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆