C#性质-集合问题
我在C#工作,我开始玩房地产。我不知道的一件事是,将类属性的集合访问器的逻辑放在什么地方最好,以及如何处理错误 例如,假设我有这个(基本)类: 现在假设我对Age属性有一个要求,0C#性质-集合问题,c#,C#,我在C#工作,我开始玩房地产。我不知道的一件事是,将类属性的集合访问器的逻辑放在什么地方最好,以及如何处理错误 例如,假设我有这个(基本)类: 现在假设我对Age属性有一个要求,0
public int Age
{
get
{
return _Age;
}
set
{
if (value < 0 || value > 99)
// handle error
else
_Age = Convert.ToInt32(value);
}
}
公共信息时代
{
得到
{
回归年龄;
}
设置
{
如果(值<0 | |值>99)
//处理错误
其他的
_年龄=转换为32(值);
}
}
还是通过创建Person对象的类
static void Main(string[] args)
{
Person him = new Person();
int NewAge = -10;
if (NewAge < 0 || NewAge > 100)
// handle error
else
him.Age = NewAge;
}
static void Main(字符串[]args)
{
人他=新的人();
int NewAge=-10;
如果(新年龄<0 | |新年龄>100)
//处理错误
其他的
他。年龄=新年龄;
}
现在,如果NewAge出现问题(它不符合我的约束条件),该怎么办?我应该创建一个自定义异常并抛出它吗?我是否应该打印一条信息,说明提供有效年龄
我在谷歌上搜索了一下,找不到任何能完全回答我问题的东西。我需要一本书:-/使用属性设置器,它就是为了这个原因(向字段添加功能)
如果传入了超出范围的值,您可以将其抛出或设置为最小(或最大)值,但这取决于您的流程要求。将其放入属性中。这是房产的主要用途之一
考虑到你将把责任放在尽可能低的层次上。您给出的示例只需要value参数就可以做出决策。它甚至不依赖于同一类的其他成员。类的其他成员没有理由知道Age属性的有效性是如何工作的,当然也没有理由让任何其他代码知道它。您将希望将逻辑放入setter中,如果它不符合要求,则抛出异常。但是,您还需要创建一个IsValidAge静态方法或其他方法,以便创建Person的类可以检查年龄值,而不仅仅是查看它是否抛出异常。或者,您可以使用MinAge和MaxAge属性,以便调用代码可以检查它们将要设置的年龄是否介于两者之间
不过,不要创建自定义异常类型,请使用ArgumentOutOfRangeException或类似的方法。您可能需要查看IDataErrorInfo接口
通过在类中实现此接口,您将向其他机制打开该类,这些机制可以从附加错误信息中获益。使用setter,并使用ArgumentOutOfRangeException,其他人已经说过
有时,您将调用另一个方法,通常类似于OnAgeChanged(int age),您可以在其中执行验证(这可能是对另一个方法的调用,以便您可以在任何地方使用它)并调用事件处理程序,如果连接到该方法,则可能会应用其他逻辑,具体取决于您使用对象的方式。在您的场景中可能不需要这样做,但对于属性来说,这样做是非常常见的。尤其是当你要更新一个表单时,表单会挂接到AgeChanged事件中进行自我更新。我将扮演魔鬼代言人的角色,并给出一个答案,说明你为什么不想把它放在setter中。在很多情况下,您希望能够设置年龄属性的值,并在以后询问该对象在整体意义上是否有效 例如,让您的属性保持简单:
public int Age { get; set; }
然后,当传入一个无效值时,您可以使用一些IsValid函数来指示相关对象是否正常。这可能非常有用,因为您可以执行更复杂的验证,而不是简单的年龄限制
bool IsValid()
{
if (Age < 0 || Age > 99)
return false;
}
这只是伪代码,但你明白我的意思。这是在setter内部无法实现的,或者至少不能以可维护的方式实现。我将这样实现它:
public int Age
{
get
{
return _Age;
}
set
{
if (IsValidAge(value))
_Age = value;
else
throw new ArgumentOutOfRangeException("value", string.Format("value should be between {0} and {1} inclusive.", MinAge, MaxAge));
}
}
private bool IsValidAge(int age)
{
return (age >= MinAge && age <= MaxAge);
}
公共信息时代
{
得到
{
回归年龄;
}
设置
{
if(有效期(值))
_年龄=价值;
其他的
抛出新的ArgumentOutOfRangeException(“value”,string.Format(“value应该介于{0}和{1}之间。”,MinAge,MaxAge));
}
}
私人旅行社有效期(国际)
{
return(age>=MinAge&&age如果您正在进行分解设计(即,在对象的生命周期中,对象的状态在所有点都有效这一点很重要),那么您可能需要在构造函数中设置并检查它。在组件设计中,您需要在使用该属性的方法中检查它,例如
class Person
{
public int calculateTimeToExpiration()
{
if (Age < 0 || Age > 100)
//throw
}
}
班级人员
{
public int calculateTimeToExpiration()
{
如果(年龄<0 | |年龄>100)
//扔
}
}
静态void main是客户端代码,不是业务逻辑的好地方。谢谢您的回答!如果您好奇,我将我的小示例(尽管现在更详细)改为(基于注释)
班级人员
{
私有字符串_FirstName=“Joe”;
私有字符串_LastName=“Smith”;
私家侦探的年龄=18岁;
私有const int MinAge=1;
私有常量int MaxAge=99;
公众人士()
{
}
公众人物(字符串名、字符串名、整数)
{
this.FirstName=FirstName;
this.LastName=LastName;
这个。年龄=年龄;
}
公共字符串名
{
得到
{
返回_FirstName;
}
设置
{
_FirstName=值;
}
}
公共字符串姓氏
{
得到
{
返回_LastName;
}
设置
{
_LastName=值;
}
}
公共信息
{
得到
{
回归年龄;
}
设置
{
if(有效期(值))
public int Age
{
get
{
return _Age;
}
set
{
if (IsValidAge(value))
_Age = value;
else
throw new ArgumentOutOfRangeException("value", string.Format("value should be between {0} and {1} inclusive.", MinAge, MaxAge));
}
}
private bool IsValidAge(int age)
{
return (age >= MinAge && age <= MaxAge);
}
class Person
{
public int calculateTimeToExpiration()
{
if (Age < 0 || Age > 100)
//throw
}
}
class Person
{
private string _FirstName = "Joe";
private string _LastName = "Smith";
private int _Age = 18;
private const int MinAge = 1;
private const int MaxAge = 99;
public Person()
{
}
public Person(string FirstName, string LastName, int Age)
{
this.FirstName = FirstName;
this.LastName = LastName;
this.Age = Age;
}
public string FirstName
{
get
{
return _FirstName;
}
set
{
_FirstName = value;
}
}
public string LastName
{
get
{
return _LastName;
}
set
{
_LastName = value;
}
}
public int Age
{
get
{
return _Age;
}
set
{
if (IsValidAge(value))
throw new ArgumentOutOfRangeException("value","Please enter a positive age less than 100.");
else
_Age = value;
}
}
private bool IsValidAge(int age)
{
return (age < MinAge || age > MaxAge);
}
public override string ToString()
{
if (Age == 1)
return "My name is " + FirstName + " " + LastName + " and I am " + Age + " year old.";
else
return "My name is " + FirstName + " " + LastName + " and I am " + Age + " years old.";
}
}
static void Main(string[] args)
{
Person him, her;
try
{
him = new Person("Joe Bob", "McGruff", 1);
Console.WriteLine(him);
}
catch (ArgumentOutOfRangeException range)
{
Console.WriteLine(range.Message);
}
try
{
her = new Person();
her.Age = -5;
Console.WriteLine(her);
}
catch (ArgumentOutOfRangeException range)
{
Console.Write(range.Message);
}
Console.ReadKey();
}
public int Age
{
get
{
return _Age;
}
set
{
if (!IsValidAge(value))
throw new ArgumentOutOfRangeException("Age","Please enter a positive age less than 100.");
_Age = value;
}
}
private bool IsValidAge(int age)
{
return (age > MinAge && age < MaxAge);
}