【问题标题】:C# Properties: Validation in getters or setters?C# 属性:在 getter 或 setter 中验证?
【发布时间】:2016-12-23 16:23:21
【问题描述】:

假设你有一个像这样的私有变量

private int _x;

你有一个属性可以提供对该变量的外部访问:

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

是否更好地放置“验证”逻辑(值非负,在界限内等) 在 getter 部分还是 setter 部分?似乎两者都可以接受,但是有首选的选择吗?

【问题讨论】:

  • 把它放在 getter 中意味着调用者永远不会知道他们做错了什么。
  • 您希望在 setter 中使用它,因为每次检索值时都没有必要验证它,除非您出于某种原因直接更新 _x。
  • 补充@DavidG 所说的...如果您放入吸气剂,您会验证什么?验证通常(总是?)验证用户输入,以确保损坏(无效)数据不会进入系统。它进入二传手。
  • 对,这是有道理的。如何将此问题标记为已回答?我是新来的(发布问题,而不是查看问题)。
  • 让@David 将他的评论放在答案中,并将其标记为已接受。

标签: c# properties


【解决方案1】:

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

您会注意到MSDN Example 使用setter 进行输入验证。

【讨论】:

  • 您提到的示例可能不是为了推广这种做法,它可能只是为了演示语法。事实上,当出现错误时它甚至什么都不做。
【解决方案2】:

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

当您在设置器中失败时,用户会立即知道问题所在,并可以修复它。如果您等到他们尝试检索该值时,您等得太晚了,用户可能不知道出了什么问题,也不知道哪里出了问题。

如果在代码的其他地方使用了无效值,您将在整个应用程序中传播不良数据,使事情变得更糟,甚至让用户更不清楚出了什么问题。

【讨论】:

    【解决方案3】:

    验证逻辑应该在setter中,以防止无效数据甚至到达_x。这样,您的类中就有一个有用的不变量_x 将始终包含一个有效值。

    执行验证的惯用方法是在消费代码尝试将无效值分配给 X 时抛出 ArgumentException or any of its subclasses

    【讨论】:

      【解决方案4】:

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

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-02-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多