调用通用对象列表作为参数

时间:2018-08-07 14:05:14

标签: c# .net generics reflection

我正在尝试迭代对象中的所有值和嵌套类中的值。我在调用通用元素列表时遇到问题。

  

System.Collections.Generic.List类型的对象[System.Object]   无法转换为类型   System.Collections.Generic.List [ConsoleApp.Class1]。

public class Class1 {

    public string a { get; set; }
    public string b { get; set; }
}
public class Class2
{
    public string c { get; set; }
    public Class1 d { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        //test dataset
        List<Class2> testItem = new List<Class2>();
        List<Class1> tmp = new List<Class1>();
        testItem.Add(new Class2() { c = "1", d = new Class1() {a="1", b="2" } });
        testItem.Add(new Class2() { c = "1", d = new Class1() { a = "1", b = "2" } });
        int i = 0;
        NestedToString(testItem, ref i);
    }

    public static void NestedToString<T>(List<T> query, ref int iteratorStart)
    {
        var t = typeof(T);
        var Headings = t.GetProperties();
        for (int i = iteratorStart; i < Headings.Count(); i++)
        {
            if (Headings[i].PropertyType.FullName == "System.String")
            {
                Console.Write(iteratorStart.ToString() + " " + Headings[i]);
                var nested = query.Select(p => Headings[i].GetValue(p)).ToList();
                foreach (var item in nested) Console.Write(" - " + item);
                Console.WriteLine();
                iteratorStart++;
            }
            else
            {
                Type type = Type.GetType(Headings[i].PropertyType.FullName);
                var mi = typeof(Program);
                var met = mi.GetMethod("NestedToString");
                var genMet = met.MakeGenericMethod(type);
                var nested = query.Select(p => Headings[i].GetValue(p)).ToList();
                genMet.Invoke(null, new object[] { nested, i });
            }
        }
    }
}

此示例代码仅在控制台迭代器,属性名称和列表中的值上编写。编写值可以正常工作,但是调用则不能。类型很好,但是出于某种原因,调试器将对象解释为List<object>而不是List<Class1>

1 个答案:

答案 0 :(得分:2)

var nested = query.Select(p => Headings[i].GetValue(p)).ToList();

这将创建一个List<object>,因为PropertyInfo.GetValue()返回object。您也需要将其转换为您的类型。

您可以这样做(避免通过反射调用另一个通用方法):

var nested = (IList)Activator.CreateInstance(typeof(List<>).MakeGenericType(type));
foreach (var value in query.Select(p => Headings[i].GetValue(p)))
    nested.Add(value);

genMet.Invoke(null, new object[] { nested, i });