C#属性:在getter或setter中进行验证?

C#属性:在getter或setter中进行验证?,c#,properties,C#,Properties,假设有这样一个私有变量 private int _x; 您拥有一个属性,该属性提供对该变量的外部访问: public int X { get { return _x; } set { _x = value; } } 是否最好使用“验证”逻辑(值非负、在范围内等) 在getter部分还是setter部分?这两种方法似乎都可以接受,但是否有首选选项?首选setter,原因如下:最好在输入垃圾值时向用户抛出并执行

假设有这样一个私有变量

private int _x;
您拥有一个属性,该属性提供对该变量的外部访问:

public int X 
{
    get 
    {
        return _x;
    }
    set
    {
        _x = value;
    }
} 
是否最好使用“验证”逻辑(值非负、在范围内等)
在getter部分还是setter部分?这两种方法似乎都可以接受,但是否有首选选项?

首选setter,原因如下:最好在输入垃圾值时向用户抛出并执行异常或显示消息,而不是允许垃圾值,并使您的类受制于内部坏数据


您将注意到,使用setter进行输入验证。

您希望您的代码尽快失败,此时您尝试设置一个无效值

当您在setter中失败时,用户立即知道问题,并可以修复它。如果您一直等到他们尝试检索该值,那么您等待的太晚了,用户可能不知道哪里出了问题,或者不知道哪里出了问题


如果代码中的其他地方使用了无效值,则会在整个应用程序中传播错误数据,使情况变得更糟,用户更不清楚出错的原因。

验证逻辑应该在setter中,以防止无效数据到达
\u x
。这样,类中就有了一个有用的不变量:
\ux
将始终包含一个有效值


执行验证的惯用方法是,当消费代码试图将无效值赋给
X

时,应首先调用验证。如果您想使用这种方法,您应该在
set
子句中实现您的逻辑。 如果你想创建漂亮的干净代码,你应该考虑它的专用方法,例如:

public class Test
{
    public int X { get; private set; }

    public void SetX(int value)
    {
         //... your logic, throw exception if validation failed
         X = value;
    }
}

你的类应该让你的对象保持有效状态。

将它放入getter意味着调用方永远不会知道他们做错了什么。你希望它在setter中,因为没有必要在每次检索值时都验证它,除非你出于某种原因直接更新x。再加上@DavidG所说的。。。如果你加入getter,你在验证什么?验证通常(总是?)验证用户输入,以确保损坏(无效)的数据不会进入系统。它在二传中。对,这是有道理的。如何将此问题标记为已回答?我是新来的(发布问题,而不是查看问题)。让@David在答案中添加他的评论,并将其标记为已接受。您提到的示例可能不是为了推广这种做法,它可能只是演示语法。事实上,当出现错误时,它甚至不做任何事情。