11

所以我听说在这样的属性中验证一个值:

//dummy example, let's assume that I want my value without dots
public string MyProp
{
    set
    {
        if(value.Contains('.'))
            throw new ArgumentException("Must not contain '.'", "value");
    }
}

是错误的,我应该避免它。

但在早些时候,我被告知这是好方法。我们可以使用封装,只有一个地方可以检查,DRY 等。

我的小例子有什么问题?

4

3 回答 3

13

在属性设置器中抛出异常并没有错。但是你应该抛出一个ArgumentException, 并实际设置属性的值!

private string _myprop;
public string MyProp{
    set{
       if(value.Contains('.')) throw new ArgumentException("Must not contain .");
       this._myprop=value;
    }
    get { return this._myprop; }
}

来自MSDN 中有关最佳实践的文章

属性 getter 应该是没有任何先决条件的简单操作。如果 getter 可能抛出异常,请考虑将属性重新设计为方法。此建议不适用于索引器。由于参数无效,索引器可能会引发异常。

从属性设置器抛出异常是有效且可接受的。

于 2013-04-08T17:38:45.390 回答
0

SO上也有一些类似的问题。

你的属性应该尽可能的轻量级。如果 setter 抛出错误,这没关系,但您可能会再次考虑将其移动到函数中。事情很容易变得一团糟。

避免从属性获取器中抛出异常。属性 getter 应该是简单的操作,不应该有前置条件。如果 getter 可以抛出异常,它可能应该重新设计为方法。

最佳实践:从属性中抛出异常

从属性设置器抛出什么异常?

于 2013-04-08T17:37:17.690 回答
-2

请参阅:最佳实践:从属性中抛出异常,以了解和讨论为什么从属性中抛出异常是不好的。

诚然,该帖子谈到了财产获取者。

消费者通常将 Setter 视为简单地设置属性隐藏的私有字段,并可能根据需要执行一些额外的操作,异常是意外行为,您能想象必须将每个 set 语句包含在 try 块中吗?

虽然它可能是被准则接受的行为,但对于开发人员来说,这是一场猜测的噩梦,并且验证逻辑应该包含在一个单独的方法中,然后在需要时从属性中调用。

如果您在设置属性时需要验证或特殊行为,您应该使用 set 方法,例如SetMyProp(string value),因为它带来了可能导致异常等的区别。

如果您将这些属性用于 WPF 模型之类的东西,那么您应该改用 WPF 的内置数据验证。

于 2013-04-08T17:32:34.823 回答