首页 > 解决方案 > 如何获取列表通过C#中的反射在类中的属性?

问题描述

我有一个名为Animals包含两个的类List<T>。一个是熊的列表,一个是企鹅的列表。

Bears只需调用变量,我就可以很简单地获得熊的名单animals——但我如何通过反射获得它?

我创建了一个静态帮助程序类ListHelper,它具有一个泛型方法,它采用BearPinguin作为泛型类型,动物作为参数,如果是泛型类型,它应该返回熊的列表Bear

那不会发生。相反,它会因这条消息崩溃:System.Reflection.TargetException: 'Object does not match target type,我不明白为什么,因为当我通过调试器检查它时类型是正确的。

下面是完全“工作”的例子。

using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System;

class ReflectionTrouble
{
    static void Main(string[] args)
    {
        var animals = new Animals
        {
            Bears = new List<Bear> {new Bear {Name = "Bear1"}, new Bear {Name = "Bear 2"}},
            Pinguins = new List<Pinguin> {new Pinguin {Name = "Pingo1"}, new Pinguin {Name = "Pingo2"}}
        };

        var lists = ListHelper.GetList<Bear>(animals);
        foreach (var bear in lists)
        {
            Console.WriteLine(bear.Name);
        }
        //expected to have printed the names of the bears here...
    }
}

public static class ListHelper
{
    public static IEnumerable<T> GetList<T>(Animals animals)
    {
        var lists = animals.GetType().GetRuntimeProperties().Where(p => p.PropertyType.IsGenericType);
        foreach (var propertyInfo in lists)
        {
            var t = propertyInfo.PropertyType;
            var typeParameters = t.GetGenericArguments();
            foreach (var typeParameter in typeParameters)
            {
                if (typeParameter == typeof(T))
                {
                    // This is where it crashes.
                    var list = (IEnumerable<T>) propertyInfo.GetValue(t);
                    return list;
                }
            }
        }

        return Enumerable.Empty<T>();
    }
}


public class Animals
{
    public IList<Bear> Bears { get; set; }

    public IList<Pinguin> Pinguins { get; set; }
}

public class Bear
{
    public string Name { get; set; }
}

public class Pinguin
{
    public string Name { get; set; }
}

标签: c#reflection

解决方案


您误解了如何调用propertyInfo.GetValue. 您传递给它的参数应该是您要获取其属性值的对象。因此,在这种情况下,您需要动物属性的值,因此该行应为:

var list = (IEnumerable<T>) propertyInfo.GetValue(animals);

通过此更改,您的代码将熊返回给我。


推荐阅读