【问题标题】:Determine if property is generic List<of T> via Reflection and loop list items通过反射和循环列表项确定属性是否为通用 List<of T>
【发布时间】:2009-10-01 13:29:48
【问题描述】:

我正在通过反射循环对象中的所有属性:

For Each p As PropertyInfo In values.[GetType]().GetProperties()
    If p.CanRead Then
        'Do stuff
    End If  
Next

谁能告诉我如何确定有问题的属性是否是泛型 List(Of T)?如果是,我需要循环列表本身。

我已经尝试过 GetType 和 TypeOf,但没有成功。

谢谢。

****更新和澄清**

为了澄清,我想保持这个通用性。我不想指定 T 的类型,我需要循环列表项并在每个项上调用 ToString 方法。 T 可以是多种不同类型之一(特定于应用程序的引用类型)。是否可以在不指定类型的情况下执行此操作?

(带有 .Net 2.0 的 VB.NET 2005)

【问题讨论】:

    标签: vb.net generics reflection


    【解决方案1】:

    试试这个完整的控制台应用程序。抱歉,它在 C# 中。

    using System;
    using System.Reflection;
    using System.Collections.Generic;
    using System.Collections;
    
    namespace ReflectionTest
    {
        public class Object1
        {
            public override string ToString()
            {
                return "This is Object 1";
            }
        }
        public class Object2
        {
            public override string ToString()
            {
                return "This is Object 2";
            }
        }    
    
        public class ContainerClass
        {
            public List<object> objects { get; set; }
            public int propA { get; set; }
            public string propB { get; set; }
            public string[] propC { get; set; }
        }
        class Program
        {
            static void Main(string[] args)
            {
                // Sample class instance
                ContainerClass c = new ContainerClass();
    
                // Add some sample data
                c.objects = new List<object>();
                c.objects.Add(new Object1());
                c.objects.Add(new Object2());
    
                PropertyInfo[] props = c.GetType().GetProperties();
    
                foreach (PropertyInfo p in props)
                {
                    if (typeof(IList).IsAssignableFrom(p.PropertyType) 
                        && p.PropertyType.IsGenericType)
                    {
                        IList item = (IList)p.GetValue(c, null);
                        if (item != null)
                        {
                            foreach (object o in item)
                            {
                                Console.WriteLine(o.ToString());
                            }
                        }
                    }
                }
                Console.ReadLine();
            }
    
    
        }           
    }
    

    【讨论】:

      【解决方案2】:

      这是 Roatins 在 VB.Net 中的回答,完整的控制台应用程序

      Imports System
      Imports System.Reflection
      Imports System.Collections.Generic
      Imports System.Collections
      
      Namespace ReflectionTest
          Public Class Object1
              Public Overloads Overrides Function ToString() As String
                  Return "This is Object 1"
              End Function
          End Class
          Public Class Object2
              Public Overloads Overrides Function ToString() As String
                  Return "This is Object 2"
              End Function
          End Class
      
          Public Class ContainerClass
              Public Property objects() As List(Of Object)
                  Get
                  End Get
                  Set
                  End Set
              End Property
              Public Property propA() As Integer
                  Get
                  End Get
                  Set
                  End Set
              End Property
              Public Property propB() As String
                  Get
                  End Get
                  Set
                  End Set
              End Property
              Public Property propC() As String()
                  Get
                  End Get
                  Set
                  End Set
              End Property
          End Class
          Class Program
              Shared Sub Main(args As String())
                  ' Sample class instance
                  Dim c As New ContainerClass()
      
                  ' Add some sample data
                  c.objects = New List(Of Object)()
                  c.objects.Add(New Object1())
                  c.objects.Add(New Object2())
      
                  Dim props As PropertyInfo() = c.[GetType]().GetProperties()
      
                  For Each p As PropertyInfo In props
                      If GetType(IList).IsAssignableFrom(p.PropertyType) AndAlso p.PropertyType.IsGenericType Then
                          Dim item As IList = DirectCast(p.GetValue(c, Nothing), IList)
                          If item <> Nothing Then
                              For Each o As Object In item
                                  Console.WriteLine(o.ToString())
                              Next
                          End If
                      End If
                  Next
                  Console.ReadLine()
              End Sub
      
      
          End Class
      End Namespace
      

      【讨论】:

      • 呃,在 stackoverflow 上这样做不违法吗??
      • 只是想帮助那家伙。我使用了 converter.telerik.com
      【解决方案3】:

      您可以在 VB.NET 中使用。 (我使用 .NET 4.5)。 如果您的原始对象是 List(of T) 且变量 name=MyData,则

      Dim CurCols() as PropertyInfo = MyData.GetType.GetGenericArguments()(0).GetProperties
      

      上面的代码给出了 MyData List 中的所有属性。

      循环遍历主列表 (MyData) 中的属性并想查找是否有任何单个属性本身是列表类型,请使用下面的 for 循环。如果不需要,您可以根据您的要求删除 IsGenericType 检查。

      For Each iCol In CurCols
          Dim colType as Type = iCol.PropertyType
          If colType.IsGenericType AndAlso colType.GetGenericTypeDefinition = GetType(List(Of)) Then
              MsgBox(iCol.Name.ToString & " Is a List Type.")
          End If
      Next
      

      【讨论】:

        【解决方案4】:
        if p.PropertyType = TypeOf List(Of T) then...
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-04-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-05-25
          • 2010-12-06
          • 1970-01-01
          相关资源
          最近更新 更多