Хорошо, извините, я просто не согласен с тем, что это ужасно и т. Д. И т. Д. Да, я бы никогда не подумал о том, чтобы заняться этим на производственной площадке - но для прототипирования, некоммерческого, только для внутреннего использования, для целей тестирования ядумаю, что использование этого подхода вполне допустимо.
Это то, что я сделал (и я подчеркиваю, что это действительно решает проблему только адекватно для анонимных типов);поднимая элементы и выталкивая их в ExpandoObject
.
Моим первоначальным изменением было сделать проекцию мульти-оператором, который возвращает ExpandoObject
:
ViewBag.SomeData = Enumerable.Range(1,10).Select(i=> {
var toReturn = new ExpandoObject();
toReturn.Value = i;
return toReturn;
});
, что почтиКороче говоря, анонимный тип просто не так чист.
Но потом я подумал, можно ли мне сойти с рук, извлекая общедоступные члены из анонимного типа (возможно, полагается на внутренние компоненты компилятора - тип внутренний,но генерируемые им свойства являются общедоступными):
public static class SO7429957
{
public static dynamic ToSafeDynamic(this object obj)
{
//would be nice to restrict to anonymous types - but alas no.
IDictionary<string, object> toReturn = new ExpandoObject();
foreach (var prop in obj.GetType().GetProperties(
BindingFlags.Public | BindingFlags.Instance)
.Where(p => p.CanRead))
{
toReturn[prop.Name] = prop.GetValue(obj, null);
}
return toReturn;
}
}
Это означает, что я могу затем использовать свой исходный код - но с небольшим вызовом метода расширения, помеченным в конце:
ViewBag.SomeData=Enumerable.Range(1,10).Select(i=> new { Value = i }.ToSafeDynamic());
ИЗнаете ли вы, что - я знаю, что это не эффективно, и большинство людей скажут, что это уродливо;но это сэкономит мне время и позволит сосредоточиться на написании функций на моем тестовом сайте, чтобы моя команда QA могла использовать их для тестирования реальных вещей (чей код, конечно, безупречен во всем :)).