2009-07-29 10 views
7

Quello che voglio fare è, in base al tipo di T, fare diverse opperazioni. Di seguito è riportato un semplice esempio del mio problema.VB.NET Funzione generica

Public Shared Function Example(Of T)() As T 
    Dim retval As T 
    If TypeOf retval Is String Then 
     Dim myString As String = "Hello" 
     retval = myString 
    ElseIf TypeOf retval Is Integer Then 
     Dim myInt As Integer = 101 
     retval = myInt 
    End If 
    Return retval 
End Function 

ottengo il "valore di tipo 'String' non può essere convertito a 'T'" Errore Lo stesso vale per la parte intera. Se lancio o su un oggetto prima di assegnarlo a retval, funziona, ma penso che sarebbe in grado di sconfiggere il mio scopo ed essere meno efficiente. Qualche idea? Grazie!

risposta

0

Sei retval = CType (LaMiaStringa, T) o retVal = CType (MyInt, T)

6

Con un metodo generico, T sarà di esattamente un tipo ogni volta. Supponiamo che tu abbia il codice di chiamata Example(Of Integer). Ora, nella tua mente, sostituisci T con Integer. Il metodo risultante conterrà queste linee (tra le altre).

Dim retval As Integer 
    If TypeOf retval Is String Then 
     Dim myString As String = "Hello" 
     retval = myString 
' more code follows ' 

Assegnare una stringa a un numero intero come quello non funzionerà mai. Certo, quel codice non verrà mai eseguito, poiché il blocco If lo impedisce, ma il codice non verrà ancora compilato. (Come parte, il codice sopra non riuscirà a compilare perché la parola chiave TypeOf è limitata per l'utilizzo con i tipi di riferimento, ma questa è un'altra storia)

In genere quando si creano metodi generici, si vorrà fare la stessa cosa con qualunque input tu abbia, ma in un modo sicuro. Se si desidera avere un comportamento diverso per diversi tipi di input, di solito si preferisce sovraccaricare i metodi.

+2

Vero, ma è ancora possibile. Tutto ciò che è necessario è che la funzione "cast" restituisca un tipo generico. Il segreto è lanciarlo per oggetto prima, e poi ricominciare. Vedi la mia risposta qui sotto. Fondamentalmente T retval = CType (CType (YourGenericVariable, Object), T) –

1
retVal = (T) "Hello World!" 
+0

Questo non funziona, perché CType (YourGenericVariable, T) non funzionerà. –

0

Una soluzione alternativa è incapsulare questo tipo di logica in una classe e utilizzare la funzione VB CallByName:


    Class Aux(Of T) 
     Public Value As T 

     Private dicc As Dictionary(Of String, Object) 

     Sub New() 
      dicc = New Dictionary(Of String, Object) 
      dicc.Add("system.string", "hola") 
      dicc.Add("system.int32", 15) 
      dicc.Add("system.double", 15.0) 
     End Sub 

     Public Function Test() As T 
      Dim typeName As String = GetType(T).ToString.ToLower 

      If dicc.ContainsKey(typeName) Then 
       CallByName(Me, "Value", CallType.Set, dicc(typeName)) 
      End If 

      Return Value 
     End Function 

     Protected Overrides Sub Finalize() 
      MyBase.Finalize() 

      If Not (dicc Is Nothing) Then dicc.Clear() 
      dicc = Nothing 
     End Sub 
    End Class 
+1

Un po 'eccessivo, vero? –

7

E 'probabilmente un po' tardi, ma provate questo:

Public Shared Function CAnyType(Of T)(ByRef UTO As Object) As T 
     Return CType(UTO, T) 
    End Function 


    Public Shared Function ExecuteSQLstmtScalar(Of T)(ByVal strSQL As String) As T 
     Dim T_ReturnValue As T 

     ' Here we have the result of a DB query ' 
     Dim obj As Object = "Value from DB query cmd.ExecuteScalar" 
     Dim strReturnValue As Object = obj.ToString(); 



     Try 
      Dim tReturnType As Type = GetType(T) 

      If tReturnType Is GetType(String) Then 
       Return CAnyType(Of T)(strReturnValue) 
      ElseIf tReturnType Is GetType(Boolean) Then 
       Dim bReturnValue As Boolean = Boolean.Parse(strReturnValue) 
       Return CAnyType(Of T)(bReturnValue) 
      ElseIf tReturnType Is GetType(Integer) Then 
       Dim iReturnValue As Integer = Integer.Parse(strReturnValue) 
       Return CAnyType(Of T)(iReturnValue) 
      ElseIf tReturnType Is GetType(Long) Then 
       Dim lngReturnValue As Long = Long.Parse(strReturnValue) 
       Return CAnyType(Of T)(lngReturnValue) 
      Else 
       MsgBox("ExecuteSQLstmtScalar(Of T): This type is not yet defined.") 
      End If 

     Catch ex As Exception 

     End Try 

     Return Nothing 
    End Function 

(il secretto sta trasmettendo il risultato generico all'oggetto, quindi il casting da tipo Object a tipo di modello T).

PS:
Si sono responsabili di assicurare che il codice funziona correttamente con tipi nullable e tipi NON nullable, così come System.DbNull.Value. Ad esempio, quando la stringa è NULL e il tipo di valore restituito è booleano (non annullabile). Su un sidenote, si noti inoltre che VB Nothing NON è uguale a NULL, è uguale a C# default(T) (ad esempio System.Guid.Empty per Guid)

Problemi correlati