表示变量的值已被拒绝

本文关键字:拒绝 变量 表示 | 更新日期: 2023-09-27 18:04:53

在c#中,我正在编写一个用setter方法检查其属性值的类:

private int _grade
public int Grade {
    get { return _grade;}
    set { if (value >= this.lowerLimit) _grade = value; }
}

如果值被拒绝,我想向应用程序发出信号。我曾考虑过重构使用setGrade函数返回bool(接受/拒绝),但有能力执行someInstance。Grade++和someInstance。等级*=2是重要的。简单的函数incrementGrade和divideGrade会使代码混乱,肯定会有一些函数我忘记实现(耦合太多)。

我目前的解决方案是检查someInstance的值。设置完成后进行评分,确保设置完成。但在我看来,这只是把混乱从类转移到应用程序。实际上,确保正确设置该值是应用程序的责任。

那些更有经验的人如何处理这个问题?谢谢!

表示变量的值已被拒绝

设置有意义的值确实是调用者的责任。
通常,在值错误时将ArgumentOutOfRangeException抛出到setter中是可以接受的做法。如果调用者期望的值可能是错误的(例如用户输入),它可以catch正确的异常。

private int _grade
public int Grade {
    get { return _grade;}
    set {
        if (value < lowerLimit) {
            throw new ArgumentOutOfRangeException("value",
                string.Format("Grade must be higher than or equal to {0}.", lowerLimit)
            );
        }
        _grade = value; // will not happen if the exception was thrown
    }
}

对于不需要的null值也有ArgumentNullException,如果你的论点拒绝原因与这两种情况不同,则一般ArgumentException

一个更时髦的方法是使用Jean-Bernard建议的代码契约。
然而,这个特性还是比较新,在。net项目中没有被广泛使用。

Code Contracts添加了静态分析,以便在编译阶段发现此类错误。尽管如此,它们仍然会在运行时抛出ArgumentException

你可以使用代码契约
下面是另一个问题的答案,它有更多的资源:link

大多数情况下,我要么默默地调整给定的value在值的范围内,要么抛出一个异常,这取决于情况。

另一个选项:您可以创建一个事件PropertyValueRejected,您的类的客户端可以订阅:

public class PropertyValueRejectedEventArgs {
    public string PropertyName { get; set; }
    public object RejectedValue { get; set; }
}
public class MyClass {
    public event EventHandler<PropertyValueRejectedEventArgs> PropertyRejected;
    private int _grade = -1;
    public int Grade {
        get { return _grade; }
        set {
            if (value >= this.lowerLimit) {
                _grade = value;
            } 
            else if (PropertyRejected != null) {     
                PropertyRejected(
                    this, 
                    new PropertyValueRejectedEventArgs {
                        PropertyName = "Grade",
                        RejectedValue = value
                    }
                ); 
            }                
        }
    }
}