获取类型.获取属性 [英] GetType.GetProperties

查看:23
本文介绍了获取类型.获取属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试浏览面板中的所有控件,并找出用户为每个控件更改了哪些属性.

I am trying to run through all the controls in a panel and find which properties the user has changed for each control.

所以我有这个代码:

    Private Sub WriteProperties(ByVal cntrl As Control)

    Try
        Dim oType As Type = cntrl.GetType

        'Create a new control the same type as cntrl to use it as the default control                      
        Dim newCnt As New Control
        newCnt = Activator.CreateInstance(oType)

        For Each prop As PropertyInfo In newCnt.GetType().GetProperties
            Dim val = cntrl.GetType().GetProperty(prop.Name).GetValue(cntrl, Nothing)
            Dim defVal = newCnt.GetType().GetProperty(prop.Name).GetValue(newCnt, Nothing)

            If val.Equals(defVal) = False Then
               'So if something is different....
            End If

        Next
    Catch ex As Exception
        MsgBox("WriteProperties : " &  ex.Message)
    End Try
End Sub

现在我面临三个问题:

  1. 当属性引用图像(背景图像)时,我有一个错误:未将 ImageObject 引用设置为对象的实例.

  1. When the property refers to image (BackGround Image) I have an error : ImageObject reference not set to an instance of an object.

第二个问题是代码:

 If val.Equals(defVal) = False Then
           'So if something is different....
 End If

is 有时会在 val 和 defVal 相同时执行.如果该属性是像 FlatAppearance(具有更多子属性)这样的parentProperty",就会发生这种情况

is executes sometimes when the val and defVal are the same. This is happening in cases that the property is a "parentProperty" like FlatAppearance (which has more child properties)

我的循环不考虑基本属性,例如我想要的大小或位置

My loop doesn't look into basic properties like Size, or Location which I want

推荐答案

Re: 未设置为对象的实例,请执行类似...

Re: Not set to an instance of an object, do something like ...

If val IsNot Nothing AndAlso defVal IsNot Nothing AndAlso Not val.Equals(defVal) Then

仅当两个值都不是 Nothing(又名 Null)时才进行比较.

Which will only do the comparison if neither value is Nothing (aka Null).

不幸的是,#2 是一个基本问题 - .Equals 默认情况下检查 2 个对象引用是否指向内存中的同一个对象 - 例如,如果你这样做了

Unfortunately, #2 is a fundamental problem - .Equals by default checks if the 2 object references point at the same object in memory - eg if You did

Dim A As New SomeClass
Dim B As New SomeClass

If A.Equals(B) Then
    ...
End If

将返回 False 除非 SomeClass 有一个重写的相等比较器,而许多类没有.

Would return False unless SomeClass has an overridden equality comparer, which many classes do not.

您可以检查有问题的值是否是您知道可以比较的类型(整数、字符串、双精度等).如果没有,您可以遍历其属性并再次执行相同的检查.这将允许您比较任何类型的公共属性是否相等,但不能保证类的内部状态相同.

You could check if the value in question is a type you know you can compare (Integer, String, Double, etc). If not, you could iterate through its properties and perform the same check again. This would allow you to compare the public properties of any type for equality but wouldn't guarantee the internal state of the classes is the same.

类似(未经测试/伪)...

Something Like (Untested/Pseudo)...

Function Compare (PropA, PropB) As Boolean
    Dim Match = True
    If PropA.Value Is Nothing Or PropB.Value Is Nothing
       Match = False
    Else
       If PropA.Value.GetType.IsAssignableFrom(GetType(String)) Or
          PropA.Value.GetType.IsAssignableFrom(GetType(Integer)) Or ... Then
           Match = PropB.Value.Equals(PropB.Value)
       Else
           For Each Prop In PropA.Value.GetType.GetProperties()
               Match =  Compare(Prop, PropB.Value.GetType.GetProperty(Prop.Name))
               If Not Match Then Exit For
           Next
        End If    
    End If    
    Return Match
End Function

这仍然不理想,因为值的内部状态可能不同.

This is still not ideal as the internal states of the values may differ.

这篇关于获取类型.获取属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆