【问题标题】:linq to list<object> and get values per rowlinq to list<object> 并获取每行的值
【发布时间】:2011-10-13 09:48:00
【问题描述】:

对于测试,我需要列出一些参数设置。此列表并非按定义预定义为类型和/或其中的内容。

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 不能被解析为另一个方法的参数。)

当我在调试模式下将鼠标悬停在测试上方时,我可以看到每一行并且每一行都包含 a 到 f 作为单独的字段。

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

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

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

马蒂斯

【问题讨论】:

  • 如果您需要将此列表传递给另一个方法,几乎​​可以肯定听起来您应该添加一个专用类 - 强制转换为 List&lt;object&gt; 只是一个糟糕的解决方法
  • 你可能是对的。以后遇到类似问题时会牢记这一点。

标签: c# linq list parameter-passing


【解决方案1】:

嗯,您正在明确通过调用AsEnumerable&lt;object&gt; 删除类型信息。摆脱它,并使用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# 中的正常静态类型。
  • 使用反射访问属性。

如果你能告诉我们更多关于你在其他方法中所做的事情,那真的很有帮助。如果可以将方法设为泛型,您可能仍然可以使用匿名类型。

【讨论】:

  • 他说他将集合作为参数传递给方法,所以他不能使用 var。
【解决方案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);
}

【讨论】:

  • 嗨,鲍勃,感谢您的回复。我将为此使用动态类型。
【解决方案3】:

你可以使用反射:

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()); 
    }  

【讨论】:

  • 嗨 kleinohad,也感谢您的回复。动态类型将在这里帮助我。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多