2017-05-04 89 views
0

我在绕过我遇到的问题时遇到了麻烦。我想将一些通用规则应用于结构,并且由于它们的类型不同,我想使用通用函数来执行此操作。我的问题是,通过只能使用指定类型的参数的方法来操作结构,我无法在没有广泛的转换的情况下找到一种方法。见,例如,需要什么样的步骤来指定一个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 

我缺少的东西?为这样一个简单的任务投四次似乎很复杂,因为我是最好的/最简单的解决方案。

+4

每当你看到自己写这样的代码,那么应该打开的灯泡是*这不是通用的*。随着这种代码刚刚变得复杂而痛苦的不可避免的结果。考虑利用vb.net对动态类型的体面支持,只要使用Option Strict Off,就可以使用'As Object'。 –

回答

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方法)。