Итак, в основном вы спрашиваете, как распаковать анонимный тип из object
?
Прежде всего, я рекомендую не использовать List<object>
и просто ... создавать собственный класс.
public class SecurityScore {
public string Security { get; set; }
public DateTime Date { get; set; }
public int ZScore { get; set; }
}
Однако, если по какой-либо причине вам нужно сделать это, попробуйте этот подход от Джона Скита:
Я всегда знал, что очень просто вернуть экземпляр анонимного типа, заявив, что метод вернет объект. Однако до сегодняшнего дня мне не приходило в голову, что вы на самом деле можете вернуться к этому типу позже. Конечно, вы не можете просто использовать обычное выражение приведения - это требует, чтобы имя типа было известно во время компиляции. Но вы можете выполнить приведение в обобщенном методе ... и вы можете использовать вывод типа для предоставления аргумента типа ... и два выражения создания экземпляра анонимного типа будут использовать один и тот же тип в одной сборке, если порядок, имена и типы свойств одинаковы.
Если вы хотите изучить его решение, ознакомьтесь с его сообщением в блоге на эту тему.
Для полноты я выложу его код здесь:
static class GrottyHacks
{
internal static T Cast<T>(object target, T example)
{
return (T) target;
}
}
class CheesecakeFactory
{
static object CreateCheesecake()
{
return new { Fruit="Strawberry", Topping="Chocolate" };
}
static void Main()
{
object weaklyTyped = CreateCheesecake();
var stronglyTyped = GrottyHacks.Cast(weaklyTyped,
new { Fruit="", Topping="" });
Console.WriteLine("Cheesecake: {0} ({1})",
stronglyTyped.Fruit, stronglyTyped.Topping);
}
}
Я должен признать, что, хотя мне не очень нравится идея упаковки / распаковки анонимного типа, его подход довольно удивителен и занимает относительно мало строк кода.
Итак, теперь, когда я дал вам возможное решение, я должен спросить - почему вы делаете это таким образом, в отличие от создания простого класса?
Редактировать: Также, для полноты, вот как я могу реализовать вашу конкретную проблему, используя решение Джона Скита:
void Main()
{
// Create a list of (boxed) anonymous objects
var securitiesBoxed = new List<object>() {
new { Security = "6752 JT", Date = DateTime.Parse("1/17/2011 12:00:00 AM"), zScore = 1 },
new { Security = "6753 JT", Date = DateTime.Parse("1/17/2011 12:00:00 AM"), zScore = 2 },
new { Security = "6754 JT", Date = DateTime.Parse("1/17/2011 12:00:00 AM"), zScore = 3 },
new { Security = "6752 JT", Date = DateTime.Parse("1/18/2011 12:00:00 AM"), zScore = 1 },
new { Security = "6753 JT", Date = DateTime.Parse("1/18/2011 12:00:00 AM"), zScore = 2 },
new { Security = "6754 JT", Date = DateTime.Parse("1/18/2011 12:00:00 AM"), zScore = 3 },
new { Security = "6752 JT", Date = DateTime.Parse("1/19/2011 12:00:00 AM"), zScore = 1 },
new { Security = "6753 JT", Date = DateTime.Parse("1/19/2011 12:00:00 AM"), zScore = 2 },
new { Security = "6754 JT", Date = DateTime.Parse("1/19/2011 12:00:00 AM"), zScore = 3 }
};
// Now, to convert to a Dictionary<string, SortedList<DateTime, double>>...
var securitiesUnboxed = securitiesBoxed.Select(x => Cast(x, new { Security = "", Date = new DateTime(), zScore = 0 }))
.GroupBy(x => x.Security)
.ToDictionary(x => x.Key, x => x.OrderBy(y => y.Date));
}
// This is the static method that will cast our anonymous type
internal static T Cast<T>(object target, T example)
{
return (T) target;
}
В LINQPad , приведенный выше код приводит к следующим данным: