我是从C#世界来到VB.NET,这让我很困惑。为什么有两种方法可以做同样的事情?或者我不知道有什么不同?
以下内容之间有什么区别:
Public ReadOnly Property Test(ByVal v as String) As Integer
Get
Return SomeOperationOn(v)
End Get
End Property
和
Public Function Test(ByVal v as String) As Integer
Return SomeOperationOn(v)
End Function
你什么时候使用一个而不是另一个?
答案 0 :(得分:16)
功能没有区别,它们都会根据参数返回一个值。实际上,由于MSIL中不存在属性的概念,因此属性实际上会在编译期间转换为函数。
然而,语义,应的使用方式存在差异。属性用于表示公开对象的内部状态。另一方面,函数应该操作对象的状态,以提供特定问题的答案(查询)或以某种方式修改状态(a 命令)。
以下是一个例子:
Public Class Rectangle
Private _size As Size
ReadOnly Property Size() As Size
Get
Return _size
End Get
End Property
Public Function IsSquare() As Boolean
Return _size.Width = _size.Height
End Function
End Class
虽然Size
只是暴露了对象的属性,但IsSquare
函数实际上对对象的内部状态执行操作以便回答一个问题。
基于这个原理,VB.NET中参数化属性的最常见用例是表示项的序列的类,其中该参数用于访问序列中的特定元素通过它的位置或一些独特的钥匙。换句话说,在C#中创建所谓的indexers。
答案 1 :(得分:14)
这个问题背后有很多历史,这可以追溯到1997年微软发布COM自动化规范时。哪个允许属性setter / getters有参数。 Visual Basic是该规范的早期采用者,它在很大程度上是由语言驱动的,以找到VBX扩展模型的替代品。在那段时间里,气体耗尽,它严重依赖于16位编码模型。
C#团队对该功能采取了一种非常严肃的态度,他们绝对讨厌语法含糊不清。这不属于一种全新的语言。 VB.NET没有同样的奢侈品,他们必须至少支持上一代VB6的一些功能。
压缩前进10年,C#团队不得不受到大众需求的反击。索引属性在例如Office对象模型中很普遍。在C#版本4中,它们允许专用于COM接口的索引属性,以减轻编写C#Office代码的痛苦。此外,还添加了可选和命名参数来处理Type.Missing苦难。 dynamic 关键字支持后期绑定,这是COM和Visual Basic的另一个重要特性,在没有该关键字的情况下,真的很难在C#中做。长话短说,COM很漂亮,IUnknown的优雅是鲜明的。托尼威廉姆斯是背后的天才。视频is here非常值得关注。 COM Automation的子集IDispatch并不是那么漂亮。但它非常成功。语言会忽视它的风险。 C#没有。
这些细节可能从一个早已消失的时代听起来很神秘,但事实并非如此。下一版本的Windows API,WinRT完全基于IUnknown。否则称为“Metro”或“Modern UI”。 IDispatch无法生存,取而代之的是IInspectable。
答案 2 :(得分:7)
该属性也可以有一个setter:
Public Property Test(ByVal v as String) As Integer
Get
Return SomeDictionary(v)
End Get
Set
SomeDictionary(v) = Value
End Set
End Property
这有所不同,因为它允许你写这样的东西:
MyObject.Test(index) = SomeValue
C#只允许您通过属性索引器进行分配:
MyOjbect[index] = SomeValue;
这意味着在C#中,每种类型只能有一个索引属性。 VB.Net允许在一个类型上有多个索引属性。要获得等效的语法,C#必须直接公开底层字典,或者如果getter / setter中有其他代码(例如日志记录),则必须创建一个附加类型来包装字典。