将匿名类型的List <object>转换为Dictionary <string,SortedList <DateTime,double >>

And*_* P. 3 c# linq dictionary

我有一个函数创建一个本地List<object>,其中对象是一个匿名类型.我需要返回这些结果Dictionary<string, SortedList<DateTime, double>>.

数据列表如下所示.

{ Security = "6752 JT", Date = {1/17/2011 12:00:00 AM}, zScore = 1 }
{ Security = "6753 JT", Date = {1/17/2011 12:00:00 AM}, zScore = 2 }
{ Security = "6754 JT", Date = {1/17/2011 12:00:00 AM}, zScore = 3 }
{ Security = "6752 JT", Date = {1/18/2011 12:00:00 AM}, zScore = 1 }
{ Security = "6753 JT", Date = {1/18/2011 12:00:00 AM}, zScore = 2 }
{ Security = "6754 JT", Date = {1/18/2011 12:00:00 AM}, zScore = 3 }
{ Security = "6752 JT", Date = {1/19/2011 12:00:00 AM}, zScore = 1 }
{ Security = "6753 JT", Date = {1/19/2011 12:00:00 AM}, zScore = 2 }
{ Security = "6754 JT", Date = {1/19/2011 12:00:00 AM}, zScore = 3 }
Run Code Online (Sandbox Code Playgroud)

我想使用LINQ将这些结果放入Dictionary<string, SortedList<DateTime, double>>字典的键是安全性的位置,值是包含安全性的所有日期/ z分数值的SortedList.

当LINQ是自定义对象时,我可以在LINQ中执行此操作,但是如何使用匿名类型对象执行此操作?

注意:此查询最初是以不必要的复杂且措辞不当的方式发布的.这可能是没有人回答的原因!我要包含链接,以防你想知道为什么输出是这种形式.
C#LINQ Z-Score查询输出到Dictionary <string,SortedList <DateTime,double >>

Pan*_*cus 7

所以基本上你问的是如何从中取消匿名类型object

首先,我建议不要使用a List<object>而只是...创建自定义类.

public class SecurityScore {
    public string Security { get; set; }
    public DateTime Date { get; set; }
    public int ZScore { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

但是,如果出于任何原因需要这样做,请尝试Jon Skeet的这种方法:

我一直都知道通过声明该方法将返回对象来返回匿名类型的实例非常容易.但是,在我今天之前没有想到你之后可以实际回到那种类型.当然,您不能只使用普通的强制转换表达式 - 这需要在编译时知道类型的名称.但是你可以在泛型方法中进行强制转换......并且你可以使用类型推断来提供类型参数......如果顺序,名称和类型,两个匿名类型实例创建表达式将在同一个程序集中使用相同的类型属性是一样的.

如果您想探索他的解决方案,请查看他关于该主题的博客文章.

为了完整起见,我将在此处发布他的代码:

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);            
    }
}
Run Code Online (Sandbox Code Playgroud)

我必须承认,虽然我不喜欢装箱/取消装箱匿名类型的想法,但他的方法非常棒,占用了相对较少的代码.

所以,既然我已经给你一个可能的解决方案,我必须问 - 为什么你这样做,而不是创建一个简单的类?

编辑:同样为了完整性,我将使用Jon Skeet的解决方案实现您的特定问题:

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;
}
Run Code Online (Sandbox Code Playgroud)

LINQPad中,上面的代码产生以下数据:

linqified数据