类型转换泛型参数 [英] Typecasting generic parameters

查看:29
本文介绍了类型转换泛型参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用以下代码:

Function GetSetting(Of T)(ByVal SettingName As String, ByRef DefaultVal As T) As T
    Return If(Configuration.ContainsKey(SettingName), CType(Configuration(SettingName), T), DefaultVal)
End Function

产生以下错误:

Value of type 'String' cannot be converted to 'T'.

我可以通过任何方式指定在所有情况下,转换确实是可能的(我基本上得到整数、布尔值、双精度数和字符串).

Any way I could specify that in all cases, the conversion will indeed be possible (I'm basically getting integers, booleans, doubles and strings).

编辑:现在似乎有三种解决方案:

Edit: There seem to be three solutions now:

  • 使用 AMissico 提供的 `ValueAs` 函数
  • 转换为`object`,然后转换为`T`,并检查空值
  • 在 Convert.ChangeType 上使用 `DirectCast`

你有什么建议?

编辑 2:这段代码能用吗?

Function GetSetting(Of T)(ByVal SettingName As String, Optional ByRef DefaultVal As T = Nothing) As T
    Return If(Configuration.ContainsKey(SettingName), ConvertTo(Of T)(Configuration(SettingName)), DefaultVal)
End Function

Function ConvertTo(Of T)(ByVal Str As String) As T
    Return If(Str Is Nothing Or Str = "", Nothing, CType(CObj(Str), T))
End Function

编辑 3: [AMJ] 工作代码

Edit 3: [AMJ] Working Code

Function GetSetting(Of T)(ByVal SettingName As String) As T
    Return GetSetting(Of T)(SettingName, Nothing)
End Function
Function GetSetting(Of T)(ByVal SettingName As String, ByVal DefaultVal As T) As T
    Dim sValue As String = Configuration(SettingName)
    If Len(sValue) = 0 Then
        Return DefaultVal
    Else
        Return CType(CObj(sValue), T)
    End If
End Function

<小时>

快速测试方法


Quick Test Method

Public Sub DoIt()

    Me.Configuration.Add("KeyN", Nothing)
    Me.Configuration.Add("KeyE", String.Empty) '""
    Me.Configuration.Add("Key1", "99")
    Me.Configuration.Add("Key2", "1/1/2000")
    Me.Configuration.Add("Key3", "True")
    Me.Configuration.Add("Key4", "0")

    Dim o As Object 'using object in order to see what type is returned by methods

    o = Value(Of Integer)("KeyN", 10) '10
    o = Value(Of Integer)("KeyE", 10) '10
    o = Value(Of Integer)("Key1", 10) '99

    o = Value(Of Date)("KeyN", #11/11/2010#)
    o = Value(Of Date)("KeyE", #11/11/2010#)
    o = Value(Of Date)("Key2", #11/11/2010#)

    o = GetSetting(Of Integer)("KeyN", 10) '10
    o = GetSetting(Of Integer)("KeyE", 10) '10
    o = GetSetting(Of Integer)("Key1", 10) '99

    o = GetSetting(Of Date)("KeyN", #11/11/2010#)
    o = GetSetting(Of Date)("KeyE", #11/11/2010#)
    o = GetSetting(Of Date)("Key2", #11/11/2010#)

    Stop
End Sub

推荐答案

Value(Of T)ValueAs 方法支持可空类型.我使用 Microsoft .NET 2.0 源代码作为参考.

The Value(Of T) and ValueAs methods support nullable-types. I used Microsoft .NET 2.0 source code as a reference.

这是经过充分测试和生产就绪的代码.

This is well-tested and production ready code.

在这些库"函数中没有错误处理.调用者有责任处理发生的任何转换错误.唯一产生的转换错误是明显的错误,例如试图将字符串abc"转换为Integer.

There is no error handling in these "library" functions. It is the responsibility of the caller to handle any conversion errors that occur. The only conversion errors generated are obvious errors, such as trying to convert the string "abc" to Integer.

Public Sub DoIt()
    Dim o As Object
    o = Value(Of Integer)("foo", 10)
    o = Value(Of DateTime)("xxx", #1/1/2000#)
    o = Value(Of Boolean?)("nop", True)
    Stop
End Sub

Public Function GatherTag(ByVal tag As String) As String
    If tag = "foo" Then
        Return "99"
    Else
        Return String.Empty
    End If
End Function

''' <summary>
''' Provides strongly-typed access to the tag values. The method also supports nullable types.
''' </summary>
''' <typeparam name="T">A generic parameter that specifies the return type.</typeparam>
''' <param name="tag">The ExifTool Tag Name,</param>
''' <returns>The value, of type T, of the tag.</returns>
Public Function Value(Of T)(ByVal tag As String, ByVal defaultValue As T) As T
    Return DirectCast(ValueAs(GetType(T), tag, defaultValue), T)
End Function

''' <summary>
''' Returns the tag's value as the specified type. The method also supports nullable types.
''' </summary>
''' <param name="type">The type to return the tag value as.</param>
''' <param name="tag">The ExifTool Tag Name,</param>
''' <returns>The value of the tag as the type requested.</returns>
Public Function ValueAs(ByVal type As System.Type, ByVal tag As String, ByVal defaultValue As Object) As Object
    Dim oResult As Object = Nothing

    Dim oTag As String = GatherTag(tag)

    If Len(oTag) = 0 Then

        'use specified default value

        oResult = defaultValue

    Else

        'is requested type a generic type?

        If type.IsGenericType AndAlso type.GetGenericTypeDefinition Is GetType(Nullable(Of )) Then

            Dim oUnderlyingType As Type = Nullable.GetUnderlyingType(type)

            Dim oConstructed As Type = type.GetGenericTypeDefinition.MakeGenericType(oUnderlyingType)

            Dim oValue As Object

            oValue = System.Convert.ChangeType(oTag, oUnderlyingType)

            If oValue IsNot Nothing Then
                oResult = Activator.CreateInstance(oConstructed, oValue)
            End If

        Else

            'non-generic type

            oResult = System.Convert.ChangeType(oTag, type)

        End If

    End If

    Return oResult
End Function

这篇关于类型转换泛型参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆