2010-01-22 47 views
2

我已经创建这个“问题”作为社区维基,因为没有正确或错误的答案。我只想知道社区对这个具体问题的看法。访问您自己班级的成员:是否使用(自动)属性?

当你有一个实例变量的一类,并且还创建了只是为这些实例变量的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"; 
     // ... 
    } 
} 

(对于那些谁恨成员前缀,我道歉)

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

当然,当属性setter(或getter)做的不仅仅是包装实例变量时,事情会改变。

是否有令人信服的理由选择一个或另一个?

回答

1

我总是也使用实例变量。原因是因为属性可能会像验证参数那样执行某些操作(如在setter中),使其不为空或不为空。如果您在类代码中使用该变量,则不需要经过这些检查的额外开销(假设您知道变量值是有效的)。这些属性也可以做其他事情(例如记录日志),这些对于公共API来说很重要,但对于内部使用来说并不重要,所以最好避免开销并在我看来使用实例变量。

+0

-1大多数时候,你需要的那种业务逻辑的类中调用也是如此。所以,基本上,你会主动选择不使用财产的理由。例如如果你知道什么时候最好不要。否则,不会涉及任何开销,因为在非调试screnario中,简单的属性setter/getter无论如何都是内联的。 – 2010-01-22 14:57:07

+0

@Robert Giesecke -1给你评论。验证非空和非空的参数会带来额外的开销。如果没有必要,没有必要这样做,因为这是额外的开销(请重新阅读我的原始响应)。您甚至没有考虑到属性设置器可能需要线程安全(即使用锁定块),在这种情况下,如果您在构造函数中并初始化变量值,则不想调用该属性,因为例。同样,还有其他类型的开销,你似乎没有考虑。 – dcp 2010-01-22 16:54:10

0

我不喜欢加前缀成员,但实际上我发现我可以这样写这样的事情,并且直到运行时才发现它。哪种有点诱惑我避免使用不需要的属性......但我现在仍然这样做!

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

} 
private String myString; 
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. 
} 
0

99%。在过去,我使用了很多使用实例变量的代码,并且当有与该变量相关的错误时,我必须在引用它的每行代码上放置一个断点。

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

1

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

很难解释,但考虑到这些表达式:

mTotalPrice = mPrice * mQuantity; 

mTotalPrice = Price * Quantity; 

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

一种解决方法是通过在属性中添加相反的变化来使表达式更加复杂。

mTotalPrice = Price/Rate * Quantity 

另一种解决方法是开始使用专用字段代替。

mTotalPrice = mPrice * Quantity 

最后你会得到私人和公共使用的混合。获得一致使用的唯一方法是始终使用专用字段。

相关问题