简体   繁体   English

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

[英]C# Properties: Validation in getters or setters?

Suppose you have a private variable like so 假设你有一个像这样的私有变量

private int _x;

And you have a property that provides external access to this variable: 并且您有一个属性,可以提供对此变量的外部访问:

public int X 
{
    get 
    {
        return _x;
    }
    set
    {
        _x = value;
    }
} 

Is it better to put "validation" logic (value non-negative, within bounds, etc) in the getter portion or the setter portion? 在getter部分或setter部分中放置“验证”逻辑(值非负,在边界内等)是否更好? It seems like it might be acceptable in either, but is there a preferred option? 它似乎也可以接受,但有一个首选吗?

The setter is preferred, for the following reason: It is better to throw and exception or display a message to the user upon inputting a garbage value, rather than allowing the garbage value, and subjecting your class to internal bad data. 首选setter是出于以下原因:最好在输入垃圾值时抛出异常或向用户显示消息,而不是允许垃圾值,并使您的类受到内部错误数据的影响。

You will note that the MSDN Example uses the setter for input validation. 您将注意到MSDN示例使用setter进行输入验证。

You want your code to fail as quickly as possible, which is at the point you try to set an invalid value. 您希望代码尽快失败,这是您尝试设置无效值的时间点。

When you fail in the setter, the user knows about the problem immediately, and can fix it. 当您在设置器中失败时,用户立即知道问题,并可以修复它。 If you wait until they try to retrieve the value, you are waiting too late, and the user may have no idea what went wrong, or where. 如果你等到他们试图检索这个值,你就等了太晚了,用户可能不知道出了什么问题,或者在哪里。

If the invalid value gets used elsewhere in the code, you are propagating bad data throughout the application, making things much worse, and even less clear to the user what went wrong. 如果在代码中的其他地方使用了无效值,那么您将在整个应用程序中传播错误数据,使事情变得更糟,甚至更不清楚用户出了什么问题。

The validation logic should be in the setter, to prevent invalid data from even reaching _x . 验证逻辑应该在setter中,以防止无效数据甚至到达_x That way, you have a useful invariant in your class: _x will always contain a valid value. 这样,你的类中有一个有用的不变量_x将始终包含有效值。

The idiomatic way to perform validation is to throw an ArgumentException or any of its subclasses when the consuming code tries to assign an invalid value to X . 执行验证的惯用方法是在使用代码尝试为X分配无效值时抛出ArgumentException或其任何子类

Validation should be called first. 应首先调用验证。 If you want to use this approach you should implement your logic in set clause. 如果要使用此方法,则应在set子句中实现逻辑。 If you want create nice clean code, you should consider dedicated method for it, eg: 如果你想创建漂亮的干净代码,你应该考虑它的专用方法,例如:

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

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

Your class should keep your object in valid state. 您的类应该使您的对象保持有效状态。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM