检查对象是否具有自定义属性

时间:2015-03-05 13:14:33

标签: vb.net object reflection custom-attributes deep-copy

我有一个递归的深拷贝函数来创建对象的新实例。为了提高我的功能,我想在我的对象中为某些值添加某种<noCopy>自定义属性,以防止它们被复制

要复制的对象可能如下所示:

public Class CDatabase
    public var1 as double
    private var2 as CSomeObject
    <noCopy> private var3 as double
    <noCopy> private var4 as CSomeObject
    ...
end class

我的递归函数如下所示:

public shared Function Copy(originalObject as Object) as Object

    if originalObject = nothing then
         return nothing
    end if

    if Attribute.IsDefined(originalObject.GetType, GetType(NoCopy)) 'This does not work
         return nothing
    end if 

    ~ do other recursive stuff ~

    return cloned object
end function

我的属性定义如下:

<System.AttributeUsage(System.AttributeTargets.All)>
 Public Class NoCopy
    Inherits System.Attribute
 End Class

我将克隆函数称为:

public Class Example

    dim original as Database
    dim clone as Database
    clone = original.Copy

    'This one returns true
    Dim test As Boolean = Attribute.IsDefined(original.GetType.GetMember("var3")(0), GetType(NoCopy))  

end class

当我尝试获取originalObject的属性时,我总是得到一个错误的返回值。但是当我通过直接引用该对象来做到这一点时,我得到了一个积极的结果。

1 个答案:

答案 0 :(得分:0)

好的,我找到了答案: 您无法直接检查对象的属性,但您必须通过询问其父对象来执行此操作。 感谢上帝,我使用递归函数。而不是检查我的对象是否有一个属性,它已被传递到下一个递归,我必须检查,然后才能进一步传递:

function Copy (originalObject as Object)

    ' do stuff

   for each myFieldInfo as FieldInfo in CType(originalObject.[GetType], Type).GetFields
       If Not Attribute.GetCustomAttribute(fieldInfo, GetType(NoCopy)) Is Nothing Then
            'set value to nothing
       End If

       ' do more stuff
       ' call self with field of originalObject
    next
end function

如果有人对Alexey方法的修改功能感兴趣,请将sub copyField替换为以下内容:

    Private Sub CopyFields(originalObject As Object, visited As IDictionary(Of Object, Object), cloneObject As Object, typeToReflect As Type, _
                       Optional bindingFlags__1 As BindingFlags = BindingFlags.Instance Or BindingFlags.NonPublic Or BindingFlags.[Public] Or _
                       BindingFlags.FlattenHierarchy, Optional filter As Func(Of FieldInfo, Boolean) = Nothing)
    For Each fieldInfo As FieldInfo In typeToReflect.GetFields(bindingFlags__1)
        If filter IsNot Nothing AndAlso filter(fieldInfo) = False Then
            Continue For
        End If

        If IsPrimitive(fieldInfo.FieldType) AndAlso (Attribute.GetCustomAttribute(fieldInfo, GetType(NoCopy)) Is Nothing) Then
            Continue For
        End If
        Dim originalFieldValue As Object = fieldInfo.GetValue(originalObject)
        If Not Attribute.GetCustomAttribute(fieldInfo, GetType(NoCopy)) Is Nothing Then
            fieldInfo.SetValue(cloneObject, Nothing)
        Else
            Dim clonedFieldValue As Object = InternalCopy(originalFieldValue, visited)
            fieldInfo.SetValue(cloneObject, clonedFieldValue)
        End If

    Next
End Sub

感谢Plutonix的帮助