【问题标题】:Check if property is an array检查属性是否为数组
【发布时间】:2014-05-16 02:40:22
【问题描述】:

我想检查一个类的属性是否是一个数组(这里只关心数字数组,而不是字符数组[即字符串])。然后我想遍历数组(即对每个元素“做某事”)。请参阅下面的尝试。谢谢!!

编辑:
所以,更多的信息.​​.....到目前为止,IsArray 和我显示的方法都无法检查数组。 MSDN 建议“typeof(Array).IsAssignableFrom(type)”,但我不确定如何使用此处的属性信息来实现。但也许其他人知道如何使用它们,而我只是没有正确使用。

在“Class3”中,我定义了一个数组,但没有标注它。当我在另一个线程中实例化它并在将其传递给此函数之前将其加载时,我使用“redim”。当我在此处的代码中插入断点时,我可以查看“myobject”并查看数组元素和值,但实际上我希望干净利落地使用 propertyinfo 类型来概括此方法。一旦我确定它是一个数组,我还需要能够对数组进行索引......再次使用 propertyinfo,而不是直接使用“myobject”。

Public Class Class2
Private Shared filelock As New Object
Public Shared Sub write2file(ByVal myobject As Class3)
    SyncLock filelock
        Dim sb As New StringBuilder
        Using sw As StreamWriter = New StreamWriter(File.Open(newfilename, FileMode.Append, FileAccess.Write, FileShare.None))
            'Dim pinfo() As PropertyInfo = GetType(Class3).GetProperties
            Dim pinfo() As PropertyInfo = CType(myobject.GetType.GetRuntimeProperties, PropertyInfo())
            sb.Clear()
            For Each p As PropertyInfo In pinfo
                If Not p.GetIndexParameters.Length > 0 Then 'if property is not an array
                    sb.Append(p.GetValue(myobject)).Append(",")

                Else ' if property is an array
                    For x As Integer = 0 To p.GetIndexParameters.Length - 1
                        sb.Append(p.GetValue(myobject, New Object() {x})).Append(",") 'append each value from array to the stringbuilder in .CSV format
                    Next
                End If
            Next
            sw.WriteLine(sb) 'write string to file
        End Using

    End SyncLock

End Sub

结束类

【问题讨论】:

  • 嗯,这取决于。数组可以有字符串和数字。你想对他们中的任何一个做什么?我看到您如何检查数组的长度,这很好。当它是一个数组或两者时,你只想检查它是否是数字???
  • 您可以尝试使用IsArray() 函数来检查属性是否为数组类型。 IsArray() 不会为 String 属性返回 True(因为它被识别为 Char 数组),因为您似乎担心

标签: arrays vb.net properties indexing


【解决方案1】:

好吧,这不是最漂亮的事情(在将类型与字符串进行比较时,我有点不舒服......如果有人知道更好,请告诉我),但我已经测试过它并且它有效:

For Each p As PropertyInfo In pinfo
    Dim typeString As String = p.PropertyType.Name.ToString
    If typeString = "Int32[]" Then 'if property is not an array
        sb.Append(p.GetValue(myobject)).Append(",")
    Else ' if property is an array
        For x As Integer = 0 To p.GetIndexParameters.Length - 1
            sb.Append(p.GetValue(myobject, New Object() {x})).Append(",") 'append each value from array to the stringbuilder in .CSV format
        Next
    End If
Next

这是你要找的吗?


这里只关心数值数组,不关心字符数组[即字符串]

如果“数字”是指它可以是任何类型(不仅仅是整数),并且您 100% 确定该数组是数字还是字符串(我的意思是,例如没有布尔数组),那么您可以修改成这样:

If typeString.EndsWith("[]") And typeString <> "String[]" Then

希望对你有帮助……

【讨论】:

  • 我无法让它工作。首先....."If typeString = "Int32[]" Then 'if property is not an array" 应该是 "if property is an array",但是你已经颠倒了这些,所以我不确定它是如何工作的为你。当我之前尝试过(现在使用您的解决方案)时,它只是为每个数组打印“system.single []”。
  • second:行:“对于 x As Integer = 0 To p.GetIndexParameters.Length - 1 .......... .....“不起作用,因为“p.GetIndexParameters.Length”实际上无法返回数组长度。我试过这个没有运气。
  • 首先,我的错。我的代码中有一个错误:它应该是Dim typeString As String = p.PropertyType.Name.ToString,所以它不会用“系统”来打扰你。部分。我现在将编辑我的答案。 它只是为每个数组打印“system.single[]”。:这不是表示“single”类型的数组吗?因此是一个数字数组。这就是为什么如果您确定它是数字数组或字符串数​​组,我强烈建议使用答案的第二部分。我并没有真正检查 Append 的行为,只是作为问题的“数字数组”识别......
【解决方案2】:

用类似这样的东西替换 If 块,它似乎可以与具有 Int32() 数组属性的简单 Class3 实现一起使用:

If p.PropertyType.IsArray Then
  ' Untested loop code for array case
Else
  ' Untested code for scalar (non-array) case
End If

似乎还没有人推荐 PropertyType 属性,但这非常关键。

【讨论】:

    猜你喜欢
    • 2016-11-04
    • 2017-08-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-27
    • 2021-12-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多