首先,我想达到的目的:
我想通过提供额外的属性来扩展值数据类型,尤其是为了验证在声明时提供的范围。我希望新数据类型也成为值类型。
与 Ada 比较:
subtype Day_Number is Integer range 1 .. 31;
理想但显然无法实现的是:
Dim DayNumber As Int64 Range 1 To 31
但是,我会很高兴:
Dim DayNumber As RangeInt64(1, 31)
如果初始化 需要时间,那没关系。一旦提供了范围,它们就被认为是不可变的。从那时起,数据类型仅用于设置/获取值,就像普通值类型一样,只是它们要根据最初提供的范围进行验证。
我的尝试:
由于我无法继承结构以扩展它们,所以我尝试将一个结构合并到一个结构中作为成员。
在一个模块中,我有这样的结构:
Friend Structure SRangeValueType(Of T)
Private lMinimum As T
Private lMaximum As T
Friend Property Minimum As T
Get
Return lMinimum
End Get
Set(tValue As T)
lMinimum = tValue
End Set
End Property
Friend Property Maximum As T
Get
Return lMaximum
End Get
Set(tValue As T)
lMaximum = tValue
End Set
End Property
Friend Sub New(Minimum As T, Maximum As T)
lMinimum = Minimum
lMaximum = Maximum
End Sub
End Structure
我尝试将此通用结构用作另一个结构(具体类型 Int64)的成员:
Public Structure RangeInt64
Private Range As SRangeValueType(Of Int64)
End Structure
但是,这不是使用带有两个参数的构造函数。
假设我想初始化 Range(结构 RangeInt64 的唯一成员),最小值和最大值分别为 100 和 200。
我不允许使用类似的东西:
Private Range As SRangeValueType(Of Int64)(100,200)
将我的值提供给通用构造函数的正确语法是什么?
最佳答案
通常情况下,如果你给一个结构添加一个构造函数,你可以使用New
关键字来调用它:
Dim x As SRangeValueType(Of Int64) ' Calls the default, infered, parameter-less constructor
Dim y As New SRangeValueType(Of Int64)(100, 200) ' Calls the explicitly defined constructor
然而,这并不是真正的问题。问题是您试图在结构中设置非共享字段的默认值。那是永远不允许的事情。结构中的所有非共享字段必须默认为其默认值(即 Nothing
)。例如:
Public Structure RangeInt64
Private x As Integer = 5 ' Error: Initializers on structure members are valid only for 'Shared' members and constants
Private y As New StringBuilder() ' Error: Non-shared members in a structure cannot be declared 'New'
End Structure
而且,正如您可能已经知道的那样,您也不能覆盖结构上默认的、推断的、无参数的构造函数:
Public Structure RangeInt64
Public Sub New() ' Error: Structures cannot declare a non-shared 'Sub New' with no parameters
x = 5
y = New StringBuilder()
End Sub
Private x As Integer
Private y As StringBuilder
End Structure
因此,您被卡住了。按照设计,当使用默认构造函数时,结构中的所有字段必须始终默认为 Nothing
。但是,如果您真的非常需要它成为一个结构,并且您不能只将它转换为一个类,并且您确实需要更改它的默认值,那么理论上您可以通过使用属性来包装它来伪造它的工作领域:
Public Structure RangeInt64
Private _Range As SRangeValueType(Of Int64)
Private _RangeInitialized As Boolean
Private Property Range As SRangeValueType(Of Int64)
Get
If Not _RangeInitialized Then
_Range = New SRangeValueType(Of Int64)(100, 200)
_RangeInitialized = True
End If
Return _Range
End Get
Set(value As SRangeValueType(Of Int64))
_Range = value
End Set
End Property
End Structure
不言而喻,它非常恶心,应尽可能避免。
更新
既然您已经提供了有关您要完成的目标的更多详细信息,我想我可能会为您提供更好的解决方案。你说得对,结构不支持继承,但它们支持的是接口(interface)。因此,如果您只需要一堆范围类型,每个值类型一个,都具有相同的最小值和最大值属性,但都返回不同的预定值,那么您可以这样做:
Private Interface IRangeValueType(Of T)
ReadOnly Property Minimum As T
ReadOnly Property Maximum As T
End Interface
Private Structure RangeInt64
Implements IRangeValueType(Of Int64)
Public ReadOnly Property Minimum As Long Implements IRangeValueType(Of Int64).Minimum
Get
Return 100
End Get
End Property
Public ReadOnly Property Maximum As Long Implements IRangeValueType(Of Int64).Maximum
Get
Return 200
End Get
End Property
End Structure
关于vb.net - 在通用 VB.NET 结构中,如何访问其显式提供的构造函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55574690/