代码之家  ›  专栏  ›  技术社区  ›  Ahmed

如果一个参数为空,最佳做法是什么?

  •  19
  • Ahmed  · 技术社区  · 16 年前


     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
        }
    



    附言

    8 回复  |  直到 15 年前
        1
  •  18
  •   Lou Franco    16 年前

      ArgChecker.ThrowOnStringNullOrEmpty(userName, "Username");
    

      public static void ThrowOnStringNullOrEmpty(string arg, string name)
      {
          if (string.IsNullOrEmpty(arg))
            throw new ArgumentNullException(name + " can't be null");
      }
    

    您还可以尝试使用参数arg处理参数列表,例如:

      public static void ThrowOnAnyStringNullOrEmpty(params string[] argAndNames)
      {
           for (int i = 0; i < argAndName.Length; i+=2) {
              ThrowOnStringNullOrEmpty(argAndNames[i], argAndNames[i+1]);
           }
      }
    

      ArgChecker.ThrowOnAnyStringNullOrEmpty(userName, "Username", Email, "email");
    
        2
  •  18
  •   Matt Howells    16 年前

    Guard ,使用如下:

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

    这在方法开始时减少了大量的干扰,并且表现良好。

        3
  •  9
  •   Welbog    16 年前

    思考以下原则 design by contract ,特别是你的职能的先决条件是什么,并标准化执行它们的方法(马特和卢在他们的答案中都建议了这一点,所以我不需要详细说明)。

    另一个需要考虑的重要因素是方法签名的大小。如果你的方法有很多参数,这可能意味着你的抽象不好。如果将参数分组到集合对象中并将这些对象用作参数,则可以减少必须进行的参数检查次数。您可以将参数检查移动到这些对象,而不必在使用它们的每个函数中检查它们。

    因此,与其将十个相关参数传递给每个函数,不如找出每个函数中使用的几个参数,并将它们打包到一个对象中,并在该对象中包含验证参数的方法。如果需要更新关于一个参数的规则,这具有易于更改的额外优势。

        4
  •  5
  •   Shane K    11 年前

    对于我们中的C#3.0开发人员来说,将这种空检查封装在扩展方法中是一种很好的方法。

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

        5
  •  3
  •   James    16 年前

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

    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
    }
    
        6
  •  2
  •   Larry Watanabe    16 年前

    继续分别检查每个参数,尽管你或手指会因为键入Grasshopper而感到疲倦:)当你的追随者收到意外的ArgumentException并从调试运行中保存下来以确定哪个参数失败时,他们会祝福你。

        7
  •  1
  •   Daniel    4 年前

    使用A AggregateException (意味着包含多个例外),其中包含多个 ArgumentNullException parameterName 论点 它与…配合得很好 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);
    
        8
  •  0
  •   pashute    6 年前

    我给你的第一个建议是买ReSharper。它会告诉你什么时候可能存在空值的问题,什么时候不需要检查它们,点击鼠标就会添加检查。话虽如此。..

    private myType myMethod(字符串param1,int param2,byte[]param3) { 检查参数(“myMethod”,{param1,param2,param3}); //其余代码。..

    在你的实用程序类中放上:

    ///<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