Lambda表达式循环通过类属性

时间:2014-04-04 02:05:59

标签: vb.net reflection lambda expression

如果我说我有以下课程:

Public Class Vehicle
        Sub New()
            Car = New Car()
            VehicleName = String.Empty
        End Sub

        Public Property Car As Car

        <Mask()>
        Public Property VehicleName As String
    End Class

    Public Class MaskAttribute
        Inherits Attribute

        Public Property Masking As String
    End Class

    <Serializable()>
     Public Class Car
        Sub New()
            CarName = String.Empty
        End Sub

        <Mask()>
        Public Property CarName As String
    End Class

在上面的示例代码中,有一个自定义属性名称Mask。

鉴于,有一个对象Dim v As new Vehicle()

如何获取具有Mask自定义属性的该对象的所有属性?

所以在这种情况下,预期的循环是Properties:CarName和VehicleName,因为它们都有掩码属性

我理解如果使用反射,性能会慢一些,而不是使用lambda表达式。如果我错了,请纠正我。

使用lambda表达式实现该目标的想法吗?

谢谢!

1 个答案:

答案 0 :(得分:0)

使用以下代码获取包含所有属性描述符的列表,其中包含Mask对象的v属性(您在示例中使用的名称):

    Dim props As List(Of PropertyDescriptor) = (
                From C As PropertyDescriptor In TypeDescriptor.GetProperties(v.GetType)
                Where C.Attributes.OfType(Of MaskAttribute)().Count > 0
                Select C
    ).ToList

您需要导入System.ComponentModel


检索属性值

如果您需要property的值,可以使用以下代码(Access property using its name in vb.net):

Public Function GetPropertyValue(ByVal obj As Object, ByVal PropName As String) As Object
    Dim objType As Type = obj.GetType()
    Dim pInfo As System.Reflection.PropertyInfo = objType.GetProperty(PropName)
    Dim PropValue As Object = pInfo.GetValue(obj, Reflection.BindingFlags.GetProperty, Nothing, Nothing, Nothing)
    Return PropValue
End Function

请注意,在我们的示例中,属性的名称由列表Name中每个PropertyDescriptor的属性props给出。


<强>更新

这在你的例子中不起作用,因为你在车辆类型的其他对象中有一个车型对象,而我没有考虑内部对象。

我发现使用它的方法是使用递归:

Sub GetPropertiesWithMaskAttribute(Obj As Object, ByRef props As List(Of PropertyDescriptor))
    Dim props1 As List(Of PropertyDescriptor) = (From C As PropertyDescriptor In TypeDescriptor.GetProperties(Obj) Select C).ToList
    For Each prop In props1
        If prop.Attributes.OfType(Of MaskAttribute)().Count > 0 Then
            props.Add(prop)
        Else
            If prop.ComponentType.IsClass Then
                GetPropertiesWithMaskAttribute(GetPropertyValue(Obj, prop.Name), props)
            End If
        End If
    Next
End Sub

这样打电话:

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    Dim props As New List(Of PropertyDescriptor)
    GetPropertiesWithMaskAttribute(v, props)
End Sub

然后props列表将包含具有MaskAtribute属性的所有属性。注意我使用了之前声明的子GetPropertyValue