2009-07-29 31 views
7

Điều tôi muốn làm là dựa trên loại T thực hiện các opper khác nhau. Dưới đây là một ví dụ đơn giản về vấn đề của tôi.VB.NET Generic Function

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 

Tôi nhận được lỗi "Value of Type 'String' Không thể được chuyển đổi thành 'T'" Cùng với phần nguyên. Nếu tôi bỏ qua một đối tượng trước khi gán cho họ để trả lại nó hoạt động nhưng tôi nghĩ rằng sẽ đánh bại mục đích của tôi và ít hiệu quả hơn. Bất kỳ ý tưởng? Cảm ơn!

Trả lời

0

Đừng retval = CType (myString, T) hoặc retval = CType (Myint, T)

6

Với một phương pháp chung chung, T sẽ được chính xác một loại mỗi lần. Giả sử bạn có mã gọi Example(Of Integer). Bây giờ, trong tâm trí của bạn, hãy thay thế T bằng Integer. Phương thức kết quả sẽ chứa các dòng này (trong số các dòng khác).

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

Gán chuỗi cho số nguyên như vậy sẽ không bao giờ hoạt động. Chắc chắn, mã đó cũng sẽ không bao giờ thực thi, vì khối If ngăn chặn điều đó, nhưng mã sẽ vẫn không biên dịch. (Không phải bên, mã trên sẽ không biên dịch được vì từ khóa TypeOf bị hạn chế sử dụng với các loại tham chiếu, nhưng đó là một câu chuyện khác)

Thông thường khi tạo các phương pháp chung, bạn sẽ muốn làm điều tương tự bất kỳ đầu vào nào bạn nhận được, nhưng theo kiểu an toàn. Nếu bạn muốn có hành vi khác nhau cho các loại đầu vào khác nhau, bạn thường tốt hơn bằng cách thay thế các phương thức thay thế.

+2

Đúng, nhưng vẫn có thể. Tất cả những gì cần thiết là hàm 'cast' trả về một kiểu generic. Bí mật được đúc nó để đối tượng đầu tiên, và sau đó bỏ lại. Xem câu trả lời của tôi dưới đây. Về cơ bản T retval = CType (CType (YourGenericVariable, Object), T) –

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

Điều này không hiệu quả, vì CType (YourGenericVariable, T) sẽ không hoạt động. –

0

Một giải pháp khác là đóng gói loại logic trong một lớp học và sử dụng VB CallByName chức năng:


    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

Một chút quá mức cần thiết, phải không? –

7

Đây có thể là hơi muộn, nhưng cố gắng này:

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 

(các secrect là đúc kết quả chung của bạn để đối tượng, sau đó đúc từ loại Object để mẫu loại T).

PS:
Bạn chịu trách nhiệm để đảm bảo rằng mã của bạn hoạt động một cách chính xác với các loại nullable và các loại KHÔNG nullable, cũng như System.DbNull.Value. Ví dụ khi chuỗi là NULL và kiểu giá trị trả về là Boolean (không nullable). Trên một sidenote, xin vui lòng cũng lưu ý rằng VB Không có gì là không bằng NULL, nó bằng với C# 's default(T) (ví dụ: System.Guid.Empty for Guid)