函数返回具有参数中指定类型的对象 [英] Function returning an object with type specified in the argument
问题描述
如何创建一个函数,该函数返回特定类型的对象,该函数的用户在参数中指定该对象(使用 vb.net 2010)?
How can I create a function that returns an object of a certain type, which the user of the function specify in the argument (using vb.net 2010) ?
Private Function TryThis(ByVal t As Type) As Object
Dim n = New t
Return n
End Function
上面的代码不起作用,但也许它可以解释我想要实现的目标.
The code above doesn't work, but maybe it can explain what I want to achieve.
使用此功能,我想从数据表中提取数据传输对象.客户端将调用此函数,指定客户端需要哪个 DTO,此函数将创建该 DTO 并使用反射 GetType.GetProperties()
填充属性.
Using this feature, I want to hydrate my data transfer objects from datatable. Client will just call this function, specifying which DTO the client wants, and this function will just create that DTO and populating the properties with reflection GetType.GetProperties()
.
推荐答案
这是一个使用泛型的非常基本的示例.方法 GetPropFromDatabase
只使用了一个 Select Case
,但您显然会调用真正的数据库查找调用.
Here's a very basic example that uses generics. The method GetPropFromDatabase
just uses a Select Case
but instead of that you'd obviously put your real database lookup call.
Option Explicit On
Option Strict On
Public Class Form1
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim X = CreateObject(Of TestClass)()
Trace.WriteLine(X.PropertyA)
Trace.WriteLine(X.PropertyB)
Me.Close()
End Sub
''//Of T as New means that the object must have a constructor
Private Function CreateObject(Of T As New)() As T
''//Create our object
Dim O As New T
''//Get the type properties
Dim Props = GetType(T).GetProperties()
''//Loop through each property
For Each P In Props
''//Set the value of our return type by property name
P.SetValue(O, GetPropFromDatabase(P.Name), Nothing)
Next
''//Return our object
Return O
End Function
''//This function would obviously do a lot more
Private Shared Function GetPropFromDatabase(ByVal name As String) As String
Select Case name
Case "PropertyA"
Return "Value1"
Case "PropertyB"
Return "Value2"
End Select
Throw New ApplicationException(String.Format("Unknown database column : {0}", name))
End Function
End Class
Public Class TestClass
Public Property PropertyA As String
Public Property PropertyB As String
End Class
编辑
根据对象的设置方式,您可能需要在 GetProperties()
上使用 BindingFlags
.
You might have to play with BindingFlags
on GetProperties()
depending on how your object is setup.
编辑 2
您可能还想考虑使用自定义属性.例如,如果您的数据库中有一个名为 [First Name]
的列,由于空间原因,该列显然不能作为对象属性存在.使用自定义属性,您可以标记某些要以特殊方式忽略或解析的属性.下面的代码显示了上述代码的扩展版本.
You might also want to look into using Custom Attributes. For instance, if you've got a column in your database called [First Name]
that obviously can't exist as an object property because of the space. With a custom attribute you can flag certain properties to be ignored or parsed in a special manner. The code below shows an extended version of the above code.
Option Explicit On
Option Strict On
Public Class Form1
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim X = CreateObject(Of TestClass)()
Trace.WriteLine(X.PropertyA)
Trace.WriteLine(X.PropertyB)
Trace.WriteLine(X.FirstName)
Me.Close()
End Sub
''//Of T as New means that the object must have a constructor
Private Function CreateObject(Of T As New)() As T
''//Create our object
Dim O As New T
''//Get the type properties
Dim Props = GetType(T).GetProperties()
''//Will hold the name of the database column to get the value of
Dim PropName As String
''//Will hold our collection of attributes on the property
Dim CustomAttributes() As Object
''//Loop through each property
For Each P In Props
''//Default the value to the property name
PropName = P.Name
''//Try to get any custom attributes for the property
CustomAttributes = P.GetCustomAttributes(True)
''//See if we have anything to work with
If (CustomAttributes IsNot Nothing) AndAlso (CustomAttributes.Count > 0) Then
''//Loop through each attribute
For Each A In CustomAttributes
''//If the attribute is our custom one defined below
If TypeOf A Is ColumnNameInDatabase Then
''//Use the manually set column name instead
PropName = DirectCast(A, ColumnNameInDatabase).ColumnNameInDatabase
''//No reason to loop through any more attributes so exit
Exit For
End If
Next
End If
''//Set the value of our return type by property name
P.SetValue(O, GetPropFromDatabase(PropName), Nothing)
Next
''//Return our object
Return O
End Function
''//This function would obviously do a lot more
Private Shared Function GetPropFromDatabase(ByVal name As String) As String
Select Case name
Case "PropertyA"
Return "Value1"
Case "PropertyB"
Return "Value2"
Case "First Name"
Return "Bob Dole"
End Select
Throw New ApplicationException(String.Format("Unknown database column : {0}", name))
End Function
End Class
Public Class TestClass
Public Property PropertyA As String
Public Property PropertyB As String
<ColumnNameInDatabase("First Name")> Public Property FirstName As String
End Class
Public Class ColumnNameInDatabase
Inherits Attribute
Private _ColumnNameInDatabase As String
Public ReadOnly Property ColumnNameInDatabase As String
Get
Return Me._ColumnNameInDatabase
End Get
End Property
Public Sub New(ByVal columnNameInDatabase As String)
Me._ColumnNameInDatabase = columnNameInDatabase
End Sub
End Class
这篇关于函数返回具有参数中指定类型的对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!