构造对象时强制执行约束的最佳方法

时间:2011-03-20 15:29:37

标签: c#

我有一个Prize对象,它有一个带有单个int参数pence的构造函数。我不希望允许传递负值。强制执行此限制的最佳方法是什么?我应该从构造函数中抛出异常吗?或者写一个工厂方法?

编辑:奖项对象用作一般角色的示例。在这个具体的例子中,使用uint是一个很好的答案,而不是一般角色。我使用3.5而没有额外的代码合同库。

4 个答案:

答案 0 :(得分:3)

  

我有一个奖品对象   单个int的构造函数   参数便士。我不想让不允许   要传递的负值。

为什么不使用uint的{​​{1}}数据类型呢?然后它已经保证它是一个正值,你不必自己强制执行这个约束。

一般来说,为了强制执行约束,咒语是“尽快失败”(另请参阅fail fast),因此您应该在构造函数中抛出异常或者使用a强制执行约束code contract。我并没有真正看到工厂方法在这种情况下会有什么帮助。

答案 1 :(得分:1)

构造实例(ctor或factory)的设计选择与参数验证无关。通常您应该支持构造函数(例如,请参阅此答案以获取框架设计指南中的相关摘录):

When to use Factory method pattern?

验证参数的简单方法当然是引发相应异常的保护条款:

public Prize(int pence)
{
    if (pence < 0)
    {
        throw new ArgumentException(...);
    }

    /* Do stuff */
}

然后您还可以查看Code Contracts。我认为那些允许你注释你的要求,但我还没有机会尝试它们。

答案 2 :(得分:0)

正如您使用int而不是string强制传入有效整数一样,如果您只想要非负整数,那么使用相应的类型如何:{{1} }。

答案 3 :(得分:0)

我同意BrokenGlass 100%。

您可以使用在奖品对象上拥有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