我已经将这个“问题”创建为社区维基,因为没有正确或错误的答案。我只想知道社区对这个具体问题的看法。
如果你有一个带有实例变量的类,并且你还创建了只是这些实例变量的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)不仅仅包装实例变量时,事情会发生变化。
是否有令人信服的理由选择其中一个?
答案 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中放置断点,如果我需要调试实例变量的问题,而不是(可能)在代码中分散了很多断点。