访问您自己类中的成员:是否使用(自动)属性?

时间:2010-01-22 14:05:42

标签: c# coding-style properties design-patterns

我已经将这个“问题”创建为社区维基,因为没有正确或错误的答案。我只想知道社区对这个具体问题的看法。

如果你有一个带有实例变量的类,并且你还创建了只是这些实例变量的getter和setter的属性,你应该使用你自己的类中的属性,还是应该总是使用实例变量?

在C#3.0中拥有自动属性使得这个决定变得更加困难。

使用属性:

public class MyClass
{
    private string _name;

    // could be an auto-property of-course
    public string Name { get { return _name; } set { _name = value; } }

    public void Action()
    {
        string localVar = Name;
        // ...
        Name = "someValue";
        // ...
    }
}

使用实例变量:

public class MyClass
{
    private string _name;

    public string Name { get { return _name; } set { _name = value; } }

    public void Action()
    {
        string localVar = _name;
        // ...
        _name = "someValue";
        // ...
    }
}

(对于那些讨厌会员前缀的人,我道歉)

就个人而言,我总是使用后者(实例变量),因为我觉得属性只能由其他类使用,而不是你自己。这就是为什么我大多远离自动财产。

当然,当属性设置器(或getter)不仅仅包装实例变量时,事情会发生变化。

是否有令人信服的理由选择其中一个?

6 个答案:

答案 0 :(得分:2)

这是一个经常被问到的问题。这是我的文章,描述了一些问题:

http://blogs.msdn.com/ericlippert/archive/2009/01/14/automatic-vs-explicit-properties.aspx

答案 1 :(得分:1)

我也总是使用实例变量。原因是因为属性可能正在执行诸如验证参数(如在setter中)的内容,因为它不是null或非空。如果您在类代码中使用变量,则无需经历这些检查的额外开销(假设您知道变量值有效)。这些属性也可能正在做其他事情(例如,日志记录),这对公共API很重要,但不适用于内部用法,所以再次,最好避免开销,只是在我看来使用实例变量。 / p>

答案 2 :(得分:1)

如果代码使用自己的公共接口,我认为更改内部实现变得更加困难。

很难解释,但请考虑以下表达方式:

mTotalPrice = mPrice * mQuantity;

mTotalPrice = Price * Quantity;

如果我需要更改内部以用€而不是$表示所有价格(不影响仍使用$的公共接口),在第二个表达式中可以做什么?

一种解决方案是通过添加与属性更改相反的方式使表达式更复杂。

mTotalPrice = Price / Rate * Quantity

另一种解决方案是开始使用私有字段。

mTotalPrice = mPrice * Quantity

最后,您将获得私人和公共用途。获得一致使用的唯一方法是始终使用私有字段。

答案 3 :(得分:0)

我不喜欢为成员添加前缀,但实际上我发现我可以意外地写出这样的内容,直到运行时才发现它。哪种诱惑让我避免使用他们不需要的属性......但我现在仍然这样做!

Public String MyString
{
   { get { return this.MyString; } }  //<== Stack Overflow
   { set { this.myString = value; } } 

}
private String myString;

答案 4 :(得分:0)

我认为这两种方法没有区别。

自动实现的属性只是访问以任何方式创建的私有成员的快捷方式。

来自MSDN的示例:

class Customer
{
    // Auto-Impl Properties for trivial get and set
    public double TotalPurchases { get; set; }
    public string Name { get; set; }
    public int CustomerID { get; set; }

    // Constructor
    public Customer(double purchases, string name, int ID)
    {
        TotalPurchases = purchases;
        Name = name;
        CustomerID = ID;
    }
    // Methods
    public string GetContactInfo() {return "ContactInfo";}
    public string GetTransactionHistory() {return "History";}

    // .. Additional methods, events, etc.
}

答案 5 :(得分:0)

99%的时间我使用属性而不是实例变量。在过去,我使用了大量使用实例变量的代码,当有一个与该变量相关的错误时,我不得不在引用它的每一行代码上放置一个断点。

我决定使用属性(公共或私有)来包装实例变量。这样做意味着我只需要在属性的getter / setter中放置断点,如果我需要调试实例变量的问题,而不是(可能)在代码中分散了很多断点。