.NET - 何时应该使用属性而不是变量+访问器函数?

5

在.NET中,有没有一种情况是我应该使用以下方式而不是使用具有读/写功能的属性?

private S as string

public function GetS() as string
     return S
end function

public sub SetS(byval NewS as string)
    S = NewS
end function

属性是否只是提供了做同样事情的更高效方法?

在高性能应用中,属性是否比上述访问器函数慢?


这是一个重复的问题。请查看http://msdn.microsoft.com/en-us/library/ms229054.aspx作为主要参考资料,然后还可以查看https://dev59.com/hXVC5IYBdhLWcg3w2lCI, https://dev59.com/gnRB5IYBdhLWcg3wgXdV,https://dev59.com/OEbRa4cB1Zd3GeqP5foU等内容。 - Pavel Minaev
真的。抱歉,我的初始搜索没有找到任何结果。 - Brian Webster
5个回答

10

在内部,属性实际上就是一对方法。它们基本上等同于get和set访问器方法。

除非属性可能会导致意外的、潜在的长时间运行的副作用,或者有其他充分理由使用方法,否则应该使用属性。

有关详细信息,请阅读MSDN上的属性使用指南。特别是在以下情况下使用方法:

  • 操作是转换,例如Object.ToString。
  • 操作足够昂贵,您希望向用户传达他们应该考虑缓存结果。
  • 使用get访问器获取属性值会产生可观察到的副作用。
  • 连续两次调用成员会产生不同的结果。
  • 执行顺序很重要。请注意,类型的属性应该能够以任何顺序设置和检索。
  • 成员是静态的,但返回可以更改的值。
  • 成员返回一个数组。

否则,我会使用属性。 Brad Abram在其博客中列出了一些其他细节,包括某些API函数使用方法的充分理由(主要是因为它们可能会导致跨计算机通信,这属于“副作用”类别)。


@Reed - 为什么有人需要私有属性? - Brian Webster
1
它使添加在完成任务时发生的逻辑变得更加容易,并且简化了版本控制(如果以后您决定需要在其中设置额外的逻辑)。 JIT会将简单属性内联,因此几乎没有理由不使用它们。 此外,私有属性可以与数据绑定一起使用。 - Reed Copsey
"成员返回一个数组" 应该被概括为 "成员返回一个引用类型的可变对象,该对象不再归属于其所属的对象。" - Pavel Minaev
@Reed - 那有点帮助。听起来你会为对象的内部提供一个包装器。对于简单的字符串或整数成员来说可能不是最明智的做法,但对于捕获对象的一些元信息可能非常有用。我的理解是否正确?感谢上面提供的链接。 - Brian Webster
1
是的。如果您认为将来可能需要提供“包装器”,那么这是一个好主意。例如,如果以后您想要实现INotifyPropertyChanged或进行其他更改跟踪,则将私有字段作为属性很有用,因为您可以在不更改其他代码的情况下更改它。 - Reed Copsey

3

在使用属性或函数时,另一个决定是实例化父对象。VB具有极为方便的语法,例如:

Dim MyStudent as Student With {.Name = "Bobby", .Age = 10}

在 With 部分只有属性可用。

我维护一个应用程序,其中有许多持久化对象存储在数据库中,这些对象之间存在很多关系。例如,一个学生有一位老师,而这名老师被持久化在数据库中。

通常我会使用 WriteOnly 属性来设置教师,因为这是一个轻量级的操作,但是由于检索教师可能需要昂贵的数据库访问,所以我使用一个函数来检索。换句话说:

Public Writeonly Property Teacher() as Teacher
Public Function GetTeacher() as Teacher

这让我可以用With { .Teacher = SomeTeacherObject }的形式实例化一个学生,但是GetTeacher鼓励在用户代码中缓存教师对象并不仅仅将其作为一个属性使用,这可能会导致多次数据库访问调用。
如果有人对这种方法有任何评论,我很乐意听取。

3

属性其实只是叫做 get_MyPropertyset_MyProperty 的方法的语法糖,因此在性能上没有区别。


2

是的,在我的经验中,我尽量避免使用属性,而是使用函数和例程代替。以下是我这样做的原因:

  1. Cannot use properties with delegates. I believe you can in C# but upon
  2. Properties are deceptive, they look like members, but behave like functions. So while you might think you are just looking at a member value you could in fact be initializing the entire system over again because the implementing developer abused lazy instantiation.
  3. Less Code, while it's not a HUGE amount, defining properties in VB requires at least 2 extra lines of code per get or set. The Overhead is double the lines of actual code for a single assignment or return operation. Although small this makes reading code much more difficult, VB is already an obsessively wordy language.

    Private ReadOnly Property Foo As String
        Get
            Return Bar
        End Get
    End Property
    

    vs

    Private Function Foo As String
        Return Bar
    End Function
    
  4. Properties are less flexible you must return what the same value you get. In Other words you can't set the value using a String and get using an Integer or overload setting with a String, or an Integer.

公正地说,我使用属性的原因是为了获得设置的=语法,但当您拥有只读属性时,这种语法并不适用。此外,属性可以在VS编辑器的属性对话框中设置。


1

使用N-Tier设计,在我的BO中,我将属性值存储为未设置的值,然后在第一次访问时进行设置。

Private _aValue As integer =-1 
    Private ReadOnly Property aValue As integer
    Get
        If _aValue = -1 Then
            _aValue = DA.General.GetaValue()
        End If
        Return _aValue
    End Get
End Property

这样,我就不必担心是否按正确顺序解析属性,因为我基本上是惰性加载它们。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接