linq к списку <object>и получение значений в строке - PullRequest
3 голосов
/ 26 июля 2011

для теста мне нужно составить список с некоторыми настройками параметров. Этот список по определению не предопределен как тип и / или что в нем.

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 и т. Д.? С уважением,

Matthijs

Ответы [ 3 ]

6 голосов
/ 26 июля 2011

Ну, вы явно удаляете информацию о типе, вызывая 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 #.
  • Доступ к свойствам с помощью отражения.

Если вы можете рассказать нам больше о том, что вы делаете в другом методе, это действительно поможет. Если метод можно сделать универсальным, вы все равно сможете использовать анонимные типы.

2 голосов
/ 26 июля 2011

Если вы удаляете всю информацию о типе времени компиляции и не можете использовать динамические объекты, то в конечном итоге вам придется использовать отражение.

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);
}
0 голосов
/ 26 июля 2011

Вы можете использовать отражение:

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