VB.NET Class 共享函数或实例函数

VB.NET Class Shared Function or Instance function

只是想知道使用函数或属性时的最佳做法是什么。 我有一个 class

Class Person
    Property FirstName as String
    Property LastName as String

    'code to use
    Return $"{LastName.ToUpper}, {FirstName}"
End Class

最好的方法是什么?

  1. ReadOnly 属性 FullName as String
  2. 函数全名作为字符串
  3. 共享函数 FullName(p as Person) as String

我的理解是 3 会更好,因为 1 或 2 将成为对象的一部分,但它们对对象所做的事情并没有什么独特之处,因此对于每个 Person 对象都会重复相同的代码。

在撰写此答案时,投票结束您的问题,因为它“可能会用意见而不是事实和引文来回答”。关于你的 3. 这肯定不是这种情况,因为单独的共享成员只能直接访问共享成员,所以这是不可能的。至于 1.2.,它们应该是这样的:

Class Person

    Public Property FirstName as String
    Public Property LastName as String

    Public Function GetFullName() As String
        Return $"{LastName.ToUpper}, {FirstName}"
    End Function

    Public ReadOnly Property FullName As String
        Public Get
            Return $"{LastName.ToUpper}, {FirstName}"
        End
    End Property

End Class

打电话给他们:

Dim p As New Person() With {.FirstName = "John", .LastName = "Doe"}
Console.WriteLine(p.GetFullName())
Console.WriteLine(p.FullName)

DOE, John
DOE, John

两者做同样的事情。意见部分来了:

在这种情况下,我更喜欢 属性,因为它不会做太多工作。我希望有一种方法可以在幕后做更多的工作——我不希望 属性 花费很多时间到 运行,但是我可以接受稍微延迟的方法——但这有点主观。来自 this answer“方法意味着执行此操作,而属性意味着获取一些数据。” 我同意(在问答中也有一些其他好的信息)。

将共享函数归入此答案的一种方法是编写一个可供实例成员使用的函数,但它不能直接访问名称属性。至于publicAPI,问题还在1.2.之间。它可能看起来像这样

Class Person

    Public Property FirstName As String
    Public Property LastName As String

    Public Function GetFullName() As String
        Return getFullName(FirstName, LastName)
    End Function

    Public ReadOnly Property FullName As String
        Get
            Return getFullName(FirstName, LastName)
        End Get
    End Property

    Private Shared Function getFullName(firstName As String, lastName As String)
        Return $"{lastName.ToUpper}, {firstName}"
    End Function

    Private Shared Function getFullName(p As Person)
        Return $"{p.LastName.ToUpper}, {p.FirstName}"
    End Function

End Class

My understanding is 3 would be better as 1 or 2 would be part of the object, but there is nothing unique in what they do to an object, so the same code would be duplicated for every Person object.

不,代码没有重复。 class 的所有对象实例都包含它们自己的 字段副本,但内存中只有一个代码副本。

实例方法可以被认为是共享方法的语法糖,它以对象实例作为第一个参数,因此2和3在内存使用方面没有区别。不过,选项 2 比选项 3 有一些优势:

  • 它更地道:myPerson.GetFullName()Person.GetFullName(myPerson) 更容易阅读。
  • 如果需要,它允许您添加多态性:实例方法可以在子class中被重写,并且实例方法可以用于实现接口。

A read-only 属性 可以认为是实例方法的语法糖,所以1和2之间也没有太大区别。 Microsoft 发布了在这两者之间进行选择的指南:

特别建议选择属性 if “该成员表示该类型的逻辑属性”,这里就是这种情况。它还列出了一些选择方法的标准(昂贵的操作、转换、后续调用的不同结果、副作用、状态复制),none 其中适用于此处。因此,我想说选项 1 是一个明显的赢家。