我在解决我遇到的问题时遇到了麻烦。我想对结构应用一些通用规则,并且由于它们的类型不同,我想使用通用函数来执行此操作。我的问题是,通过只有指定类型的参数可用的方法来操纵结构,我没有找到一种方法,没有大量的转换。例如,请参阅指定始终将DateTime
值指定为UTC所需的步骤:
Public Shared Function Sanitize(Of T As Structure)(retValue As T?) As T?
' If value is DateTime it must be specified as UTC:
If GetType(T) = GetType(DateTime) AndAlso retVal.HasValue Then
' To specify the value as UTC, it must first be casted into DateTime, as it is not know to the compiler that the type in fact IS
' DateTime, even if we just checked.
Dim retValAsObj = CType(retVal, Object)
Dim retValAsObjAsDateTime = CType(retValAsObj, DateTime)
Dim retValWithSpecifiedKind = DateTime.SpecifyKind(retValAsObjAsDateTime, DateTimeKind.Utc)
retVal = CType(CType(retValWithSpecifiedKind, Object), T?)
End If
Return retVal
End Function
我错过了什么吗?对于这样一个简单的任务,四次投射似乎很复杂,对我来说是最好/最简单的解决方案。
答案 0 :(得分:0)
您可以使用扩展方法
使用扩展方法,您无需检查类型并进行转换
使用扩展方法,您将拥有适合各种类型的方法 - 维护简单
使用扩展方法,您将拥有“可读”语法
<Extension>
Public Shared Function Sanitize(Date? nullable) AS Date?
{
If nullable.HasValue = False Then Return nullable
Return DateTime.SpecifyKind(nullable.Value, DateTimeKind.Utc)
}
<Extension>
Public Shared Function Sanitize(Integer? nullable) AS Integer?
{
If nullable.HasValue = False Then Return nullable
If nullable.Value < 0 Then Return 0
Return nullable.Value
}
代码中的某处
Dim sanitizedDate As Date? = receivedDate.Sanitize()
Dim sanitizedAmount As Integer? = receivedAmount.Sanitize()
扩展方法有一些缺点 - 例如,您无法“模拟”它们进行单元测试,这会强制您在每次使用时测试“Sanitize”方法(如果您使用的是Test-First方法)。