我想知道是否有办法限制施工中的价值。这是我的代码:
class Student : Human
{
private double Grade;
public Student(string FirstName, string LastName, double Grade)
: base(FirstName, LastName)
{
this.FirstName = FirstName;
this.LastName = LastName;
this.Grade = Grade;
}
}
当我创建一个新学生时,我希望将等级限制在> = 2.00和< = 6.00之间,就像编译错误或运行时的异常一样。有办法吗? (不要担心其他字段FirstName和LastName)
答案 0 :(得分:12)
您可以检查它并在运行时中抛出异常,如下所示:
if (grade < 2.00 || grade > 6.00)
throw new ArgumentOutOfRangeException("grade");
始终将这些条件放在方法或构造函数的开头。我甚至将它们放在他们自己的#region
中(但这是我个人的偏好):
public Student(string firstName, string lastName, double grade)
: base(firstName, lastName)
{
#region Contract
if (grade < 2.00 || grade > 6.00)
throw new ArgumentOutOfRangeException("grade");
#endregion
this.FirstName = firstName;
this.LastName = lastName;
this.Grade = grade;
}
但是,有一种方法可以使用代码约定来获取此类事件的编译时警告。您可以下载Code Contracts on MSDN,在那里您也可以找到文档。它仅与Visual Studio的非Express版本集成,由Microsoft编写。它将检查方法调用是否可能符合您指定的合同。您的代码将变为:
using System.Diagnotistics.Contracts;
public Student(string firstName, string lastName, double grade)
: base(firstName, lastName)
{
#region Contract
Contract.Requires<ArgumentOutOfRangeException>(grade >= 2.00);
Contract.Requires<ArgumentOutOfRangeException>(grade <= 6.00);
#endregion
this.FirstName = firstName;
this.LastName = lastName;
this.Grade = grade;
}
答案 1 :(得分:4)
你可以抛出异常:
class Student : Human
{
private double Grade;
public Student(string FirstName, string LastName, double Grade)
: base(FirstName, LastName)
{
if (Grade >= 2 && Grade <= 6) {
throw new ArgumentOutOfRangeException();
}
this.FirstName = FirstName;
this.LastName = LastName;
this.Grade = Grade;
}
}
如果您正在使用Microsoft Code Contracts,那么您也可以这样做:
class Student : Human {
private double Grade;
public Student(string FirstName, string LastName, double Grade)
: base(FirstName, LastName)
{
System.Diagnotistics.Contracts.Contract.Requires<ArgumentOutOfRangeException>(Grade >= 2 && Grade <= 6);
this.FirstName = FirstName;
this.LastName = LastName;
this.Grade = Grade;
}
}
答案 2 :(得分:1)
还有另一个选项,可能有点精简,但确保给定范围,根本不使用double
,而是创建一个名为Grade
的自定义类。您的Grade
课程将包含来自double
的演员表,并将强制执行验证。
这意味着所有成绩验证逻辑都在Grade
结构中,而Student
类只接收Grade
对象,而不必担心它。
public struct Grade
{
public static readonly double MinValue = 2.0;
public static readonly double MaxValue = 6.0;
private double value;
public static explicit operator double(Grade grade)
{
return grade.value + MinValue;
}
public static explicit operator Grade(double gradeValue)
{
if (gradeValue < MinValue || gradeValue > MaxValue)
throw new ArgumentOutOfRangeException("gradeValue", "Grade must be between 2.0 and 6.0");
return new Grade{ value = gradeValue - MinValue };
}
}
你会像这样使用它:
double userInput = GetUserInputForGrade();
Grade grade = (Grade)userInput; // perform explicit cast.
Student student = new Student(firstName, lastName, grade);
编辑:我已使用@ EricLippert的建议更新了代码,以使该类向开发人员公开其最小/最大值。
编辑2:使用@ JeppeStigNielsen的建议再次更新。 value
字段现在存储MinValue的偏移量,因此对default(Grade)
的调用将返回有效值(等于MinValue),无论0是否在有效范围内。
答案 3 :(得分:0)
class Student : Human
{
private double Grade;
public Student(string FirstName, string LastName, double Grade)
: base(FirstName, LastName)
{
if (Grade < 2 || Grade > 6)
throw new ArgumentOutOfRangeException("Grade must be between 2 and 6");
this.FirstName = FirstName;
this.LastName = LastName;
this.Grade = Grade;
}
}
答案 4 :(得分:0)
public Student(string FirstName, string LastName, double Grade)
: base(FirstName, LastName)
{
if(Grade >= 2.0 || Grade <= 6.00)
throw new ArgumentException("your message");
}
答案 5 :(得分:0)
如果你想要编译时间的任何机会,你必须使用代码合同。它们在运行时基本上是异常,因此等同于带有异常的参数验证。
public Student(string firstName, string lastName, decimal grade)
{
Contract.Requires(grade >= 2);
Contract.Requires(grade <= 6);
FirstName = firstName;
LastName = lastName;
Grade = grade;
}
看到这个问题
答案 6 :(得分:-2)
class Student : Human
{
private double Grade;
public Student(string FirstName, string LastName, double Grade)
: base(FirstName, LastName)
{
this.FirstName = FirstName;
this.LastName = LastName;
this.Grade = Grade;
if(Grade >= 2 and Grade <= 6){
throw new Exception("Incorrect grade input");
}
}
或者抛出你想要的相关例外,例如ArgumentOutOfrangeException等......