我应该通过属性setter还是不在C#中分配类字段
本文关键字:分配 字段 属性 setter 我应该 | 更新日期: 2023-09-27 18:26:50
正确的方法是什么?属性setter可能包含比实际赋值更多的代码。假设我有以下代码:
class Person
{
private String name;
public Person(String name)
{
this.name = Name
}
public String Name
{
get;
set {
if(String.Empty.Equals(value)) return;
this.name = value;
}
}
}
由于我不是通过属性分配的,所以上面的代码是错误的吗?
- 除非有充分的理由,否则即使在同一个类中,也应该使用属性
Name
而不是字段name
,以确保始终使用get
/set
方法中的逻辑 - 由于您显式指定了
set
实现,因此还必须显式指定get
实现以供示例编译 - 在大多数情况下,您应该使用
String.IsNullOrEmpty
,而不是像String.Empty.Equals(value)
代码这样的其他方法 -
房产的行为通常应该出人意料。运行
person.Name = "";
之后,您会期望Name
属性为""
,而不是以前的属性。如果设置null或空名称无效,则在传递此类值时应引发异常。class Person { private String name; public Person(String name) { this.Name = name; } public String Name { get { return this.name; } set { if(String.IsNullOrEmpty(value)) throw new ArgumentException("Name is required", "value"); this.name = value; } } }
通常,您应该通过属性setter进行赋值,因为setter是用来维护类不变量的。绕过setter意味着在直接修改后备字段时必须手动维护这些不变量,这会使您暴露在错误中,并可能违反DRY原则。
在您已经证明绕过setter会带来重要性能优势的特定情况下,可以忽略此规则。
属性的行为方式应该不足为奇。这意味着,如果我这样做:
someObject.SomeProperty = someValue;
然后,在这样做之后,以下情况应该为真(假设属性的类型允许比较),或者应该抛出异常:
someObject.SomeProperty == someValue;
例如,如果您不希望调用者将属性设置为null或空字符串,那么如果他们这样做了,您应该抛出一个ArgumentException
:
public String Name
{
get
{
return this.name;
}
set
{
if (string.IsNullOrEmpty(value))
throw new ArgumentException("value");
this.name = value;
}
}
我不想看到这种东西:
myObject.Name = "Fred";
// ... Lots of code
myObject.Name = "";
string test = myObject.Name;
// Now test == "Fred" wtf?