我正在构建一个使用物理特性测量的应用程序。最初,我使用了一大堆“double”类型的变量,并以匈牙利符号或在我的脑海中跟踪值:
Public Class ResultData
Public Property position_in_mm_vs_time_in_ms as Double(,)
Public Property initial_position_in_mm as Double
Public Property final_position_in_mm as Double
Public Property duration_in_ms as Double
Public Property speed_in_mm_per_s as Double
End Class
但是随着我添加更多的项目和更多的属性,这很快就变得一团糟,到处都是转换因子,无法知道一个值是米还是毫安,没有硬编码就无法知道一个项目的正确缩写是什么和手动跟踪,以及添加选项以 SI 或英制单位输入和输出数据的想法令人恐惧。
我意识到这个问题是一个打字问题,我可以使用一个具有类型和值的类来改进这种安排:
Namespace Measure
Public Class Value(Of GenericUnits)
Public Property Value As Double
End Class
Public Class ValuePoint(Of XUnits, YUnits)
Public X As Value(Of XUnits)
Public Y As Value(Of YUnits)
Public Sub New(x As Value(Of XUnits), y As Value(Of YUnits))
Me.X = x
Me.Y = y
End Sub
End Class
Public Class Units
Public Interface GenericUnits
ReadOnly Property Abbreviation As String
' Additional properties, operators, and conversion functions
End Interface
' Additional unit types
End Class
End Namespace
所以我的声明变成了:
Public Class ResultData
Public Property PositionData as List(of ValuePoint(of Units.Seconds, Units.Millimeters))
Public Property InitialPosition as Value(of Units.Millimeters)
Public Property FinalPosition as Value(of Units.Millimeters)
Public Property Duration as Value(of Units.Milliseconds)
Public Property Speed as Value(of Units.MillimetersPerSecond)
End Class
这真的很好很干净。现在我想使用我的运营商定义的属性和转换,但我不能:
Dim result As New ResultData()
Dim msg As New System.Text.StringBuilder()
msg.AppendLine("Speed units are abbreviated as: ")
msg.AppendLine(result.Speed.GetType().ToString() & "?")
msg.AppendLine(result.Speed.GetType().GenericTypeArguments(0).ToString() & "?")
' Produces error "Abbreviation is not a member of System.Type"
' Casting produces conversion error
'msg.AppendLine(result.Speed.GetType().GenericTypeArguments(0).Abbreviation & "?")
' Produces:
' Speed units are abbreviated as:
' Measure.Value`1[Measure.Units+MillimetersPerSecond]
' Measure.Units+MillimetersPerSecond
MsgBox(msg.ToString())
如何访问我的类型声明的属性和方法?
我发现我的声明Value(Of GenericUnits)
实际上并没有引用名为 的接口GenericUnits
,而是生成了一个泛型类型;我不妨称之为Value(Of T)
。我认为这可能与我的问题有关。