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

C# 构造对象时强制执行约束的最佳方法,c#,C#,我有一个Prize对象,它有一个带单个int参数pence的构造函数。我不希望允许传入负值。实施这一限制的最佳方式是什么?我应该从构造函数中抛出一个异常吗?还是写一个工厂方法 编辑:奖品对象用作一般角色的示例。在这个特定示例中,使用uint是一个很好的答案,而不是作为一般角色。我使用3.5,没有额外的代码库 我有一件奖品,上面有 具有单个int的构造函数 参数便士。我不想被允许 要传入的负值 为什么不使用uint数据类型来表示pence?然后它已经被保证是一个正值,你不必自己强制这个约束 一般来

我有一个Prize对象,它有一个带单个int参数pence的构造函数。我不希望允许传入负值。实施这一限制的最佳方式是什么?我应该从构造函数中抛出一个异常吗?还是写一个工厂方法

编辑:奖品对象用作一般角色的示例。在这个特定示例中,使用uint是一个很好的答案,而不是作为一般角色。我使用3.5,没有额外的代码库

我有一件奖品,上面有 具有单个int的构造函数 参数便士。我不想被允许 要传入的负值

为什么不使用
uint
数据类型来表示
pence
?然后它已经被保证是一个正值,你不必自己强制这个约束

一般来说,强制约束的咒语是“尽快失败”(另请参见),因此您应该在构造函数中抛出异常,或者使用一个异常来强制约束。我真的不知道工厂方法在这种情况下会有什么帮助

我有一件奖品,上面有 具有单个int的构造函数 参数便士。我不想被允许 要传入的负值

为什么不使用
uint
数据类型来表示
pence
?然后它已经被保证是一个正值,你不必自己强制这个约束


一般来说,强制约束的咒语是“尽快失败”(另请参见),因此您应该在构造函数中抛出异常,或者使用一个异常来强制约束。我真的不知道工厂方法在这种情况下会有什么帮助。

就像您使用
int
而不是
字符串来强制传递有效整数一样,如果您只需要非负整数,使用适当的类型:
uint
如何,就像使用
int
而不是
字符串来强制传递有效的整数一样,如果您只需要非负整数,那么使用适当的类型:
uint
如何我100%同意BrokenGlass

在prize对象上使用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

我100%同意BrokenGlass

在prize对象上使用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

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

当然,验证参数的简单方法是抛出适当异常的guard子句:

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

    /* Do stuff */
}
公共奖(整数便士)
{
如果(便士<0)
{
抛出新的ArgumentException(…);
}
/*做事*/
}

还有一个问题你可能想调查一下。我认为这些允许您对需求进行注释,但我还没有机会尝试它们。

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

当然,验证参数的简单方法是抛出适当异常的guard子句:

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

    /* Do stuff */
}
公共奖(整数便士)
{
如果(便士<0)
{
抛出新的ArgumentException(…);
}
/*做事*/
}

还有一个问题你可能想调查一下。我认为这些可以让您对需求进行注释,但我还没有机会尝试它们。

好主意。但是请记住,uint不符合CLS(请参阅)。这是否与您的案件相关取决于您。@nodots:这是极好的信息。我想我需要再次通读数据类型的C#规范来复习一下。好主意。但是请记住,uint不符合CLS(请参阅)。这是否与您的案件相关取决于您。@nodots:这是极好的信息。我想我需要再次通读数据类型的C#规范,以进行复习。