1

我正在使用属性来允许将单个字符串name添加到类Details中,我希望属性只接受可以拆分为两部分的字符串。

这两部分将是firstNameLastName。但是,如果生成的拆分在数组中有 1,0 或多于 2 个字符串,则输入应被视为无效,我想首先向调用该属性的任何代码抛出错误。

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

如果不是,那么以下是在检查正确性的同时将数据放入类的首选方法:

  1. 使用类中的方法Details来处理错误输入,制作该方法boolean
  2. 继续使用属性,但由调用属性的代码完成错误检查。我不喜欢这样,因为我希望类中的所有错误检查代码都是自包含的Details

.

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

4 回答 4

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];
        }
    }
于 2013-05-18T03:41:42.797 回答
2

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

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

于 2013-05-18T03:24:14.910 回答
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包提供一个插件。它可能比您在这里寻找的更复杂,但它是验证应用程序中输入和输出的好方法。

于 2013-05-18T04:01:15.930 回答
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 的方法中完成验证。

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

编辑2:

你也可以这样做:

类详细信息{私人字符串名字,姓氏;

    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
}
于 2013-05-18T03:21:21.310 回答