C# 验证属性中的值

C# 验证属性中的值,c#,dry,encapsulation,C#,Dry,Encapsulation,所以我听说在这样的属性中验证值: //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"); } } 这是错误的,我应该避免 但在早些时

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

//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");
    }
}
这是错误的,我应该避免

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

我的小示例有什么问题吗?

请参阅:有关从属性抛出异常的原因的解释和讨论

诚然,这篇文章谈到了属性获取者

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

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

如果在设置属性时需要验证或特殊行为,则应使用set方法,例如
SetMyProp(字符串值)
,因为它会带来区别,可能导致异常等


如果您正在使用WPF模型之类的属性,那么应该使用WPF的内置数据验证。

也有一些类似的问题

您的属性应该尽可能轻量级。如果设置器抛出一个错误,这是可以的,但是您可以再次考虑将其移动到一个函数。事情很容易变得一团糟

避免从属性获取程序引发异常。属性吸气剂 应该是简单的操作,不应该有先决条件。如果 getter可以抛出异常,它可能应该重新设计为 一种方法


在属性设置程序中抛出异常没有什么错。但是您应该抛出一个
ArgumentException
,并实际设置属性的值

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

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

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


它没有问题,但是a)我宁愿抛出一个
参数异常
,b)您忘记实际设置值了!你不能随便乱丢绳子。您需要引发异常。@jrummell的可能重复项不是重复项。在这个问题上,他们不讨论例外情况,这是个好办法。NET框架的几个部分做同样的事情。-1您链接到的那篇文章说明setter中的异常是可以的。来自MSDN:“从属性设置器抛出异常是有效且可接受的。”您是否看到设置器执行验证(并抛出异常)以强制执行其契约(例如,不允许设置空值)有问题?@hatchet yes,我认为对于空值,它是可以接受的,或者对于边缘情况,该值确实不能采用某种形式,但是如果在进一步使用的上下文中它是一个“错误”的值,那么在尝试使用它们时应该发生异常。为什么要猜测何时有docstring?在每个set语句周围使用
try
块的意义类似于在每个
Substring
周围使用
try
块,因为起始索引可能超出范围。检查一下数据,我不同意。设置程序抛出异常是完全可以接受的。您还将如何处理例如不允许为null的属性?如果删除setter,序列化将失败。执行
契约的能力。需要(值!=null)是必需的。谢谢!实际上,这是一个简单的演示示例。