c#:当T仅存储在类型变量中时,如何访问List <T>中的元素?

时间:2019-06-06 19:42:53

标签: c# reflection

我会尽力澄清这一点:

我有一个System.Object类型的对象,其中包含事物列表。事情在运行时确定。目前,我可以找到列表中包含的内容类型,但是我不知道如何访问它们。

这是一个代码示例,其中“ o”是有问题的事物的列表:

示例:

//Assume at this point in code, we have access to "o"
//which is type System.Object

Type thingType = thing.GetType();
Type listType = typeof(List<>);
Type listOfThingsType = listType.MakeGenericType(thingType);

if (o.GetType() == listOfThingsType)
{
    //Now I know o contains a list of things
    //...but how do I access them and work with their members?

    //foreach thing in o
    //   operate on thing through reflection
}

编辑(更多详细信息): 我正在使用反射来访问事物的属性成员。我不知道属性名称是什么。我不需要能够使用普通的C#语法。我只需要一种访问事物的方法,这样就可以将它们作为单独的对象使用。

每个HansPassant的可行解决方案。为了澄清下面的评论讨论:

将代码更改为此:

//Assume at this point in code, we have access to "o"
//which is type System.Object

Type thingType = thing.GetType();
Type listType = typeof(List<>);
Type listOfThingsType = listType.MakeGenericType(thingType);

if (o.GetType() == listOfThingsType)
{
    //Now I know o contains a list of things
    //...but how do I access them and work with their members?

    dynamic oList = o;
    foreach(object thing in oList)
    {
        //operate on thing through reflection
    }
}

2 个答案:

答案 0 :(得分:0)

List<T>实现IList。如果您只需要访问组成序列化列表的实例(或其他任何实例),请使用List而不是List<T>,因为看起来实际类型可能并不重要。当然,这也可能取决于您使用的序列化程序(您在评论中提到了该序列化程序吗?)。

Fiddle

using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;

public class Program
{
    public class MyType 
    {
        public string Name {get;set;}
        public MyType(){}
        public MyType(string name) {
          this.Name = name;
        }

        public override string ToString()
        {
            return this.Name ?? "empty";
        }
    }

    public static void Main()
    {
        List<MyType> list = new List<MyType>();
        list.Add(new MyType("One"));
        list.Add(new MyType("Two"));
        DoSomethingWithUnknown(list);
    }

    public static void DoSomethingWithUnknown(object argList)
    {
        var list = (IList)argList;
        foreach(var item in list)
        {
            Console.WriteLine("As object: " + item);
            dynamic itm = item;
            Console.WriteLine("As dynamic: " + itm.Name);
        }
    }
}

答案 1 :(得分:0)

谢谢HansPassant,他建议使用动态。

这是解决方案:

//Assume at this point in code, we have access to "o"
//which is type System.Object

Type thingType = thing.GetType();
Type listType = typeof(List<>);
Type listOfThingsType = listType.MakeGenericType(thingType);

if (o.GetType() == listOfThingsType)
{
    //Now I know o contains a list of things
    //...but how do I access them and work with their members?

    dynamic oList = o;
    foreach(object thing in oList)
    {
        //operate on thing through reflection
    }
}