我想在VB.NET中实现一个克隆类型为T的对象的扩展方法。
说,我想要
Dim cust1 as New Customer() //...
Dim cust2 as New Customer() //...
cust2 = cust1.Clone()
''
' My extension method '
''
<Runtime.CompilerServices.Extension()> _
Public Function Clone(Of T As {Class, New})(ByVal obj As T) As T
Dim objClone As New T
' clonning stuff '
' objClone = CType(GetAnObjClone(), T) '
Return objClone
End Function
Dim c As MyObject
Dim cc As MyObject = c.Clone() ' does work!!! cool... '
要删除的问题。
答案 0 :(得分:5)
克隆应该是对象本身作为常规方法执行的操作,而不是扩展方法。有关示例,请参阅MSDN documentation on MemberwiseClone。
答案 1 :(得分:0)
我实际上已经使用反射做了类似的事情,以帮助在MVC项目中进行模型绑定。我已经定义了一个自定义属性“Updatable”和一个通用的扩展方法。这有点安全,因为我必须使用我的自定义属性(或通过元数据类)明确标记要克隆的属性,以便执行任何操作,但我相信您可以根据自己的需要调整它。
这是我的自定义属性(不是很令人兴奋!)
<AttributeUsage(AttributeTargets.Property, AllowMultiple:=False)>
Public Class UpdateableAttribute : Inherits Attribute
End Class
这是扩展方法
<Extension()>
Public Sub UpdateObject(Of T)(ByVal targetObject As T, ByVal otherObject As T)
Dim metaDataType As MetadataTypeAttribute = GetType(T).GetCustomAttributes(GetType(MetadataTypeAttribute), True).FirstOrDefault
If metaDataType Is Nothing Then
For Each prop As Reflection.PropertyInfo In GetType(T).GetProperties()
If prop.GetCustomAttributes(GetType(UpdateableAttribute), True).Count > 0 Then
Dim targetValue = prop.GetValue(targetObject, {})
Dim otherValue = prop.GetValue(otherObject, {})
If Not targetValue = otherValue Then
prop.SetValue(targetObject, otherValue, {})
End If
End If
Next
Else
Dim targetProps As Reflection.PropertyInfo() = GetType(T).GetProperties()
For Each prop As Reflection.PropertyInfo In metaDataType.MetadataClassType.GetProperties()
If prop.GetCustomAttributes(GetType(UpdateableAttribute), True).Count > 0 Then
Dim propName As String = prop.Name
Dim targetProperty = targetProps.Single(Function(p) p.Name = propName)
Dim targetValue = targetProperty.GetValue(targetObject, {})
Dim otherValue = targetProperty.GetValue(otherObject, {})
If Not targetValue = otherValue Then
targetProperty.SetValue(targetObject, otherValue, {})
End If
End If
Next
End If
End Sub
对我很好,它显然使用反射所以不是闪电般的快速但是节省了很多左右编码。
如果您有权访问目标类,则可以执行此操作,在此示例中,只有firstname和surname将克隆。
Public Class Person
<Updateable()>
Public Property FirstName As String
<Updateable()>
Public Property Surname As String
Public Property ShoeSize As Integer
Public Property Gender As Gender
Public Property BirthDate As DateTime
Public Property FavoriteCarMake
End Class
使用元数据类执行相同操作的示例,如果您无法直接编辑目标类(例如,如果您不想编辑T4模板,则可以使用实体框架类),这样做很有用。
<MetadataType(GetType(PersonMetadata))>
Public Class Person
Public Property FirstName As String
Public Property Surname As String
Public Property ShoeSize As Integer
Public Property Gender As Gender
Public Property BirthDate As DateTime
Public Property FavoriteCarMake
End Class
Public Class PersonMetadata
<Updateable()>
Public Property FirstName
<Updateable()>
Public Property Surname
End Class
在这两种情况下,您都可以执行以下操作:
Dim person1 As New Person With ...
Dim person2 As New Person With ...
person1.UpdateObject(person2)