【发布时间】:2011-07-19 04:07:20
【问题描述】:
我有一个 Prize 对象,它有一个带有单个 int 参数 pence 的构造函数。我不想让负值传入。执行此限制的最佳方法是什么?我应该从构造函数中抛出异常吗?还是写一个工厂方法?
编辑: Prize 对象被用作一般角色的示例。在此特定示例中,使用 uint 是一个很好的答案,而不是一般角色。我使用 3.5 没有额外的代码契约库。
【问题讨论】:
标签: c#
我有一个 Prize 对象,它有一个带有单个 int 参数 pence 的构造函数。我不想让负值传入。执行此限制的最佳方法是什么?我应该从构造函数中抛出异常吗?还是写一个工厂方法?
编辑: Prize 对象被用作一般角色的示例。在此特定示例中,使用 uint 是一个很好的答案,而不是一般角色。我使用 3.5 没有额外的代码契约库。
【问题讨论】:
标签: c#
我有一个 Prize 对象,它有一个 具有单个 int 的构造函数 参数便士。我不想让 要传入的负值。
为什么不使用uint 数据类型来代替pence?那么它已经保证它是一个正值,你不必自己强制执行这个约束。
通常,对于强制执行约束,口头禅是“fail as soon as possible”(另请参阅fail fast),因此您应该在构造函数中抛出异常或使用@987654322 强制执行您的约束@。我真的不明白工厂方法在这种情况下会有什么帮助。
【讨论】:
如何构造实例(ctor 或工厂)的设计选择独立于参数验证。通常,您应该偏爱构造函数(例如,请参阅此答案以获取框架设计指南的相关摘录):
When to use Factory method pattern?
验证参数的简单方法当然是抛出适当异常的保护子句:
public Prize(int pence)
{
if (pence < 0)
{
throw new ArgumentException(...);
}
/* Do stuff */
}
还有Code Contracts,您可能想查看。我认为这些允许您注释您的要求,但我还没有机会尝试它们。
【讨论】:
正如您使用int 而不是string 来强制传入有效整数一样,如果您只需要非负整数,那么使用适当的类型怎么样:uint。
【讨论】:
我 100% 同意 BrokenGlass。
您可以用来在奖品对象上具有 int 属性的一个“技巧”只允许正整数而不将数据类型更改为 uint:
public class Prize
{
private int _pence = 0;
public int Pence
{
get { return _pence; }
set { _pence = Math.Max(value, 0); }
}
public Price(int pence)
{
Pence = pence;
}
}
这并不能阻止人们在使用你的类时使用反射来设置负数,但它确实会阻止负数被正常输入。
如果您不想默默地忽略负值,您可以抛出异常,甚至调用Math.Abs。
【讨论】: