.NET中的扩展通用方法(VB.NET)

时间:2010-11-10 11:26:05

标签: .net vb.net generics extension-methods

我想在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... '

要删除的问题。

2 个答案:

答案 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)