0

这样做的正确方法是什么?属性设置器可能包含比实际赋值更多的代码。可以说我有以下代码:

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

上面的代码是错误的,因为我不是通过属性分配的吗?

4

3 回答 3

8
  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;
            }
        }
    }
    
于 2013-08-08T14:57:16.323 回答
1

属性应该以一种不足为奇的方式表现。这意味着如果我这样做:

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?
于 2013-08-08T14:58:37.890 回答
1

一般来说,您应该通过属性设置器进行分配,因为设置器用于维护类不变量。绕过 setter 意味着您必须在直接修改支持字段时手动维护这些不变量,从而使您面临错误并可能违反DRY原则。

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

于 2013-08-08T14:53:59.027 回答