繁体   English   中英

我应该在C#中通过属性设置器分配类字段吗?

[英]Should I assign class fields via property setter or not in C#?

正确的做法是什么? 属性设置器可能包含的代码不仅仅包括权限分配。 可以说我有以下代码:

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;
        }
    }
}

上面的代码是否错误,因为我没有通过属性分配?

  1. 除非有充分的理由,否则,即使在同一类中,也应该使用属性Name而不是字段name ,以确保始终使用get / set方法中的逻辑。
  2. 由于您显式指定了set实现,因此还必须显式指定get实现以供示例编译。
  3. 在大多数情况下,应该使用String.IsNullOrEmpty ,而不要使用其他方法,例如String.Empty.Equals(value)代码。
  4. 属性通常应该表现得毫不奇怪。 运行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; } } } 

通常,您应该通过属性设置器进行赋值,因为设置器在那里可以维护类不变式 绕过设置方法意味着直接修改后备字段时必须手动维护这些不变式,从而使您暴露于错误中并可能违反DRY原理。

在特定情况下, 您已经证明绕过设置器会带来重要的性能优势,请随时忽略此规则。

属性的行为应该毫不奇怪。 这意味着如果我这样做:

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?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM