linq列出<object>并获取每行的值</object>

时间:2011-07-26 12:58:38

标签: c# linq list parameter-passing

对于测试我需要使用一些参数设置制作列表。此列表不是根据定义预先定义为类型和/或其中的内容。

bool[] trueOrFalse = new bool[] { true, false };
        int[] para1 = new int[] { 1, 2, 3 };
        int[] para2 = new int[] { 5, 6, 7 };
        int[] para3 = new int[] { 1, 2, 3 };
        int[] para4 = new int[] { 5, 7, 9 };

        List<object> test = (from a in trueOrFalse
                   from b in para1
                   from c in para2
                   from d in para3
                   from e in para4
                   let f = c - d
                   where c - d <= 3
                   select new { a, b, c, d, e, f }).AsEnumerable<object>().ToList();

结果很好(这只是一个测试),我确实得到了一个列表,其中包含所有可能的参数组合,我可以将其用作另一个方法的参数。 (我需要它作为列表,因为据我所知,var test不能被解析为另一个方法的参数。)

当我在调试模式下悬停在测试之上时,我可以看到每行和每行包含一个到f作为单独的字段。

但我怎样才能减去这些值?

假设我想在列表中使用foreach循环。

如何设置int myA = a等? 的问候,

Matthijs

3 个答案:

答案 0 :(得分:6)

嗯,您通过调用AsEnumerable<object> 明确删除类型信息。摆脱它,并使用var作为变量:

var test = (from a in trueOrFalse
            from b in para1
            from c in para2
            from d in para3
            from e in para4
            let f = c - d
            where c - d <= 3
            select new { a, b, c, d, e, f }).ToList();

然后你可以这样做:

foreach (var item in test)
{
    Console.WriteLine(item.a); // Strongly typed at compile-time
}

现在,我之前错过了“我可以用作另一种方法的参数”部分。 (您仍然可以使用列表 - 但它是匿名类型的列表。)使用匿名类型,您实际上是以强类型方式将结果传递给方法。

选项:

  • 创建包含所有相关数据的命名类型,以便您可以以强类型方式将其保留在该表单中。
  • 对您将数据传递给的方法使用类型推断(可能是也可能不可行;但您不清楚自己在做什么)。
  • 在C#4中使用动态类型来绕过C#中的常规静态类型。
  • 使用反射访问属性。

如果你能告诉我们更多关于你在另一种方法中所做的事情的话,那真的会有所帮助。如果该方法可以通用,您仍然可以使用匿名类型。

答案 1 :(得分:2)

如果您要删除所有编译时类型信息而无法使用动态对象,那么您最终将不得不使用反射。

var i=test.FirstOrDefault();
if (i==null) {
  // NO ITEMS IN LIST!!!
  // So do something else!
}
var type=i.GetType();
var aGetter=type.GetProperty("a");
var bGetter=type.GetProperty("b");

foreach (var item in test) {
  bool myA = (bool)aGetter.GetValue(item,null);
  int myB=(int)bGetter.GetValue(item.null);
}

答案 2 :(得分:0)

你可以使用反射:

bool[] trueOrFalse = new bool[] { true, false };
        int[] para1 = new int[] { 1, 2, 3 };
        int[] para2 = new int[] { 5, 6, 7 };
        int[] para3 = new int[] { 1, 2, 3 };
        int[] para4 = new int[] { 5, 7, 9 };

        List<object> test = (from a in trueOrFalse
                             from b in para1
                             from c in para2
                             from d in para3
                             from g in para4
                             let f = c - d
                             where c - d <= 3
                             select new { a,  b,  c, d, g,  f }).AsEnumerable<object>().ToList();
        foreach (object item in test)
        {
            Response.Write(item.GetType().GetProperty("a").GetValue(item, null).ToString()); 
        }

你也可以给你的字段命名如下:

select new { aName = a, bName = b, cName = c, dName = d, gName = g, fName =  f }).AsEnumerable<object>().ToList();

然后使用:

foreach (object item in test)
    {
        Response.Write(item.GetType().GetProperty("aName").GetValue(item, null).ToString()); 
    }