【问题标题】:Is the property accessor/mutator (getter/setter) the right place to enforce acceptable ranges?属性访问器/修改器(getter/setter)是强制执行可接受范围的正确位置吗?
【发布时间】:2012-02-06 19:15:37
【问题描述】:

在设置了端口号的应用中,我想将可分配给端口号的值限制为 49152 到 65535(含)之间的值。

我编写了一些测试方法来测试超出此范围的任何内容都会导致测试失败。它们确实失败了(正如预期的那样,因为代码尚未考虑到这一点)。

所以我的问题是:将强制无效值的代码放入有效值的最佳位置是什么 - 在这里:

public int Port
{
    get
    {
        return port;
    }
    set
    {
        port = value;
    }
}

如:

public int Port
{
  get
  {
      return port;
   }
   set
   {
       if ((value < 49152) || (value > 65535))
       {
          value = 55555;
       }
       port = value;
    }
}

...还是其他地方?

【问题讨论】:

  • DJKraze 是谁?实际上,我认为我们确实需要它,因为 49152 以下的数字可能已经在使用,而 65535 以上的数字则不可用。输入端口号的人可能不知道。
  • 这是我为了解决争论而不得不发布的一个问题的副本:stackoverflow.com/questions/635519/… 你绝对不应该分配给调用者。它隐藏了错误。这很危险(如果调用者打算输入 49152 但不小心输入了 49151,现在您已经用 55555 掩盖了这个可怕的错误,让程序继续使用与调用者预期完全不同的值)。
  • 或者如果您在分配给Port 时不小心引入了一个错误怎么办?假设你喝醉了编码,你写了x.Port = Int32.Parse(s.Substring(s.Length - 1));而不是x.Port = Int32.Parse(s);,所以现在你所有的值都是垃圾。因此,您已经让这个灾难性的错误进入您的程序。不要这样做。
  • 我添加了验证标签,因为这确实是问题所在。

标签: c# validation properties


【解决方案1】:

将强制无效值转换为有效值的代码的最佳位置是什么?

最好的地方是无处。将无效值强制为随机有效值是在调用者中隐藏错误。调用者可以提前知道他们试图设置的值是否有效,所以如果他们做错了就让他们崩溃。抛出异常,不要忽略错误并猜测它们的含义。

【讨论】:

  • 前几天我不得不向客户说明这一点。它们有一个字段,本质上是计算中的加权乘数,但它是一个可选值。他们在规范中指定将 0 视为 1。我不得不说服他们,值 0 应该被视为抛出异常,因为它不是有效值(0.01 到 2.5 是有效范围),因此表明需要修复的错误,而 null 是有效的,但应该被视为 1,以便对加权计算没有影响。
【解决方案2】:

您可以将验证逻辑放在您的 setter 中,但如果验证失败,您可能应该让其他人知道。

即:

private static int minimumPortNumber = 49152;
private static int maximumPortNumber = 65535;

public int Port
{
  get
  {
      return port;
   }
   set
   {
       if ((value < minimumPortNumber) || (value > maximumPortNumber))
       {
           throw new ArgumentOutOfRangeException("port", string.Format("The port number is out of range. It must be between {0} and {1}", minimumPortNumber, maximumPortNumber));
       }
       port = value;
    }
}

【讨论】:

  • 我喜欢这个答案,但请考虑从 setter 抛出异常以指示错误(即,如果 setter 在无效输入上抛出异常是可以的,但 setter 的调用者应验证输入以防止抛出此类异常)。进一步说明,IMO 端口应具有static readonly minport/maxport 成员。 4915265535 让我印象深刻。
  • 我完全同意布赖恩的观点。错误信息应该让开发者知道期望值是什么,不要只是告诉他们错误,告诉他们为什么错误。
【解决方案3】:

这是在字段周围使用包装方法而不直接公开它们的最大好处之一。所以我肯定会说,是的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-11-25
    • 1970-01-01
    • 2017-06-13
    • 2011-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多