在C#中检查属性内的错误输入

时间:2013-05-18 03:11:47

标签: c# properties error-handling

我使用属性允许将单个字符串name添加到类Details,我希望该属性只接受字符串,如果它可以分成两部分。

这两部分将是firstNameLastName。但是,如果结果拆分在数组中有1,0个或2个以上的字符串,那么输入应该被认为是无效的,我想首先向一个名为property的代码抛出一个错误。

可以对像这样的属性进行错误处理吗?

如果,那么在检查正确性的同时将以下内容提供给类的首选方法是:

  1. 使用类Details中的方法来处理错误输入,使该方法成为boolean
  2. 继续使用属性,但是通过调用属性的代码完成错误检查。我不喜欢这个,因为我希望所有错误检查代码都自包含在Details类中。
  3. class Details
    {
        private string firstName, lastName;
    
        public string Name
        {
            // name
            get { return firstName + " " + lastName; }
            set 
            { 
                string name = value;
                string[] nameArray = name.Split(' ');
                firstName = nameArray[0];
                lastName = nameArray[1];
            }
        }
    }
    

    编辑:我最感兴趣的是三个选项中哪些是最佳实践:

    1. 在属性内部进行错误检查。
    2. 在另一个班级的课外进行错误检查,然后只需将经过验证的输入添加到Details
    3. 使用boolean内的Details方法验证输入。

4 个答案:

答案 0 :(得分:2)

我会遵循现有的验证框架,例如FluentValidation

此外,在您的特定情况下,我将使用SetName(string fullName)方法进行解析和填充。

答案 1 :(得分:2)

为什么不使用异常来捕获错误情况。

    private string firstName, lastName;
    public string Name
    {
        get { return string.Concat(firstName, " ", lastName); }
        set
        {
            string name = value;
            if (string.IsNullOrEmpty(name)) { throw new ArgumentNullException("Name"); }

            var nameParts = name.Trim().Split(' ');
            if (nameParts.Length != 2) { throw new ArgumentException("Invalid name value"); }

            firstName = nameParts[0];
            lastName = nameParts[1];
        }
    }

答案 2 :(得分:1)

因此,我不会将不符合业务逻辑的数据视为异常,因此不会抛出异常。我要做的是:

class Details
{
    private string firstName, lastName;

    public string Name
    {
        // name
        get { return firstName + " " + lastName; }
        set 
        { 
            string name = value;
            string[] nameArray = name.Split(' ');
            if(nameArray.Length == 2) 
            {
                firstName = nameArray[0];
                lastName = nameArray[1];
            } 
            else
            {
                firstName = nameArray[0]; 
                lastName = string.Empty;
            }
        }
    }

    public bool IsValid()
    {
         return !string.IsNullOrEmpty(lastName);
    }
}

然后,您可以使用name属性,然后检查名称是否有效。如果无效,则可以采取适当的措施。

另一种选择是在调用Details.Name的方法中完成验证。

编辑:想要删除我认为不好的建议,但保持这样的评论是有意义的,所以只是把它们搞砸了

EDIT2:

您也可以这样做:

课程详情     {         private string firstName,lastName;

    public string Name
    {

        get { return firstName + " " + lastName; }
        private set;
    }

    public bool TryParseName(string name)
    {
        bool isValid = true;
        string[] nameParts = name.split(' ');
        if(nameParts.Length == 2) 
        {
             firstName = nameParts[0];
             lastName = nameParts[1];
        }
        else
        {
             isValid = false;
        }

        return isValid;
    }
}

你会去哪里

if(details.TryParseName(name))
{
    // is valid name
}
else
{
    // handle invalid name
}

答案 3 :(得分:1)

只是为了将我的观点添加到别人所说的内容中,在我看来,部分困难源于你使用属性设置器做一些非平凡的事情(拆分字符串,验证结果,然后将结果存储在两个字段中)。通常,属性(尤其是读/写属性)应仅与获取和设置单个值有关(使用只读属性返回简单的计算值也很常见)。

如果是我,我会为名字和姓氏分别使用第三个计算属性作为全名:

class Details
{
    public string FirstName { get; set; }
    public string LastName { get; set; }

    public string FullName
    {
      get { return string.Concat(this.FirstName, " ", this.LastName); }
    }
}

然后您可以添加一个方法来设置全名。一个方法比这个任务的属性设置器更合适,因为它是非平凡的,并且更有可能出现问题:

public void SetFullName(string fullName)
{
  string[] nameComponents = fullName.split(' ');

  if (nameComponents.Length != 2) 
  {
    throw new ArgumentException("The full name must contain a first and last name.");
  }

  this.FirstName = nameComponents[0];
  this.LastName = nameComponents[1];
}

我还想为Code Contracts包提供一个插件。它可能比您在这里寻找更复杂,但它是验证应用程序中输入和输出的好方法。