2013-08-11 6 views
4

В последние несколько дней я пытался найти способ итерации на List<dynamic> без особого успеха.Можно ли перебирать список <dynamic>?

Вот что я делаю:

while (dr.Read()) 
{ 
    dynamic e = new ExpandoObject(); 
    var d = e as IDictionary<string, object>; 
    for (var i = 0; i < dr.FieldCount; i++) 
     d.Add(dr.GetName(i), DBNull.Value.Equals(dr[i]) ? null : dr[i]); 

    result.Add(e); 
} 

приведенный выше код является метод, который возвращает IEnumerable<dynamic> тогда в мой контроллер я получаю данные обратно с:

dynamic irionErrorsExport = oracleDbManager.GetStrCtrlNDGWithErrors(tableName, queryParamsList, periodo, "", "", ""); 

и теперь я «Я застрял, так как мне нужно итерации на irionErrorsExport и создать« конкретный »объект/с для использования с EPPlus.

Может ли кто-нибудь сказать мне, возможно ли это, и показать простой пример?

+0

Является ли 'GetStrCtrlDGWithErrors()' ваш метод, содержащий первый фрагмент кода? – siride

+1

Покажите нам подпись метода GetStrCtrlDGWithErrors – MarcinJuraszek

+0

Обратите внимание, что вы можете сделать: 'IDictionary e = new ExpandoObject()', изменить 'd. *' В 'e. *', А затем 'result.Add (e) 'без промежуточного броска. – xanatos

ответ

1
while (dr.Read()) 
{ 
    IDictionary<string, object> e = new ExpandoObject(); 

    for (var i = 0; i < dr.FieldCount; i++) 
     e.Add(dr.GetName(i), DBNull.Value.Equals(dr[i]) ? null : dr[i]); 

    result.Add(e); 
} 

Из вызывающего метода вы «обманываете». Вы знаете, что ваша динамическая коллекция является ExpandoObject, так

foreach (IDictionary<string, object> row in result) 
{ 
    foreach (var kv in row) 
    { 
     Console.WriteLine("{0}: {1}", kv.Key, kv.Value); 
    } 
} 

В конце концов, это лучше, если ваш метод просто возвращает List<IDictionary<string, object>>, не dynamic необходимости.

Отражение динамических типов затруднено. Если вы не можете использовать утиную печать (утиная печать - это когда вы знаете, что объект может Duck(), даже если вы не знаете, что это такое, так что вы можете сделать dynamic x = something; x.Duck();), то это только полутвердый. Если вы не доверяете мне по этому поводу, вы можете попробовать чтение How do I reflect over the members of dynamic object?

1

Если вы заполните DataTable как here, Вы можете использовать Json.Net и получить бетон объект легко

//Sample DataTable 
DataTable dt = new DataTable(); 
dt.Columns.Add("IntCol"); 
dt.Columns.Add("StrCol"); 
dt.Rows.Add(new object[]{1,"1"}); 
dt.Rows.Add(new object[]{2,"2"}); 

var jsonstr = JsonConvert.SerializeObject(dt); 
var list = JsonConvert.DeserializeObject<List<YourClass>>(jsonstr); 

public class YourClass 
{ 
    public int IntCol { set; get; } 
    public string StrCol { set; get; } 
} 
2

Да, вы можете перебрать dynamic объекта:

dynamic source = new List<int>() {1, 2, 3, 4, 5, 6}; 
foreach (var item in source) 
{ 
    Console.Write(item.ToString()); 
} 

Печать 123456 в консоли.

Однако, это вызовет исключение во время выполнения, если итерация не представляется возможным:

Рассмотрим следующий код:

dynamic source = 2; 
foreach (var item in source) 
{ 
    Console.Write(item.ToString()); 
} 

RuntimeBinderException выбрасывают:

Не удается неявно преобразовать тип 'Int' к «System.Collections.IEnumerable»

Редактировать: вы должны быть осведомлены о различиях между foreach на нормальных переменных и dynamic. Они объясняются в другом вопросе SO: C# 4.0 'dynamic' and foreach statement

Смежные вопросы