【问题标题】:Checking if object has custom attribute检查对象是否具有自定义属性
【发布时间】:2015-03-05 13:14:32
【问题描述】:

我有一个递归深拷贝函数来创建对象的新实例。为了提高我的函数的功能,我想在我的对象中的某些值上放置某种<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 的属性时,我总是得到一个错误的返回值。但是,当我通过直接引用对象来执行此操作时,我会得到肯定的结果。

【问题讨论】:

  • AutoMapper 处理这种事情。
  • 如果将NoCopy 应用于字段,则无法检查属性的类型(类)。
  • 正如我所说,复制功能递归地工作。它得到一个object_1 并将object_1 中包含的任何对象传递给它自己,直到它遇到不能分解成更小的部分的原始类型。每次传递的对象都会检查 ist 属性。
  • 仍然,如果你想在Type上找到属性,你需要将它应用到Type上。示例类本身没有该属性,因此标记为does not work 的代码是正确的:CDatabase 类型没有应用该属性。
  • 很抱歉,我只见树木不见森林。如何访问我的复制函数中的对象以获取它们的属性?我在 Google 或 MSDN 上找到的每个页面都只告诉我如何检查其他对象中的成员/属性。我真的坚持这一点:-/

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


【解决方案1】:

好的,我找到了答案: 您不能直接检查对象的属性,但必须通过询问其父对象来做到这一点。 感谢上帝,我正在使用递归函数。在传递到下一个递归之后,我不必检查我的对象是否具有属性,而是必须在进一步传递之前进行检查:

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 的帮助

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-10-09
    • 2021-03-12
    • 2015-06-04
    • 2013-12-26
    • 2012-04-16
    • 1970-01-01
    • 2014-05-08
    • 2013-07-03
    相关资源
    最近更新 更多