动态创建匿名对象从列表中的值C# [英] Dynamically create anonymous object from list values c#

查看:471
本文介绍了动态创建匿名对象从列表中的值C#的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个列表(或可阵列),我想动态创建一个匿名对象的字符串。我如何做到这一点。

I have a list (or can be array) of strings that I want to dynamically create an anonymous object from. How do I do this?

var dataSet = new DataSet();
dataSet.ReadXml(@"");
var dataTable = dataSet.Tables[0];
var dataRow = dataTable.Rows[0];    

var keys = new List<string> {"Column1","Column2"};
var result = new {keys[0] = dataRow[keys[0]], keys[1] = dataRow[keys[1]]}

因此命名为钥匙该列表将被这种方法之外创建,并且可以包含1至许多值。我试图创建一个字典,并通过列表循环和增加键/值对到字典中,但随后我不能弄清楚如何转换的字典回匿名类型。我也尝试用的expando对象,但似乎没有得到我任何更远。

So that list named "keys" is going to be created outside this method and can contain 1 to many values. I tried creating a dictionary and looping through the list and adding key/value pairs to the dictionary but then I couldnt figure out how to convert the dictionary back to an anonymous type. I also experimented with the expando objects but that didn't seem to get me any farther.

我必须能够返回一个匿名类型作为此方法的结果。与LINQ查询的GROUPBY子句中使用

I must be able to return an anonymous type as the result of this method will be using with the GroupBy clause of a LINQ query.

下面是我必须动态地创建字典的方式:

Here is the method I had to dynamically create the dictionary:

    public object Key(DataRow dataRow, List<String> keys)
    {
        var dictionary = new IDictionary<string, object>;
        foreach (string key in keys)
        {
            dictionary.Add(key, dataRow[key]);
        }
        return dictionary;
    }

下面是我的LINQ查询:

Here is my LINQ query:

var duplicates = dataTable.AsEnumerable().GroupBy(r => Key(r, keys)).Where(c => c.Count() > 1).ToList();

如果我从密钥()方法匿名类型硬编码GROUPBY子句的工作。基本上我只需要GROUPBY子句基于在键列表中的值动态设置。

The GroupBy clause works if I hardcode in an anonymous type from the Key() method. Basically I just need the GroupBy clause to be dynamically set based upon the values in the keys list.

推荐答案

剥离下来你的问题,你想要的是要能团在此基础上,可以由该项目的一个或多个特性的运行时属性的项目的列表。从本质上讲,这意味着你需要,它可将项目成键选择功能(这是你的方法)。

Stripping down your question, what you want is to be able to group a list of items based on a runtime property which could be composed of one or more properties of that item. In essence, it means you need a selector function (which is your Key method) that transforms an item into a key.

为了对GROUPBY工作,它需要能够以比较关键的任何两个实例,看看它们是相等的。这意味着主要需要实现一个有意义的等于()的方法,或者您需要一个的IEqualityComparer 执行该做的工作为你。在这种情况下,我不会创建一个新的关键麻烦,只写一个相等比较,可以比较两个数据行直接:

In order for GroupBy to work, it needs to be able to compare any two instances of the key to see if they're equal. This means the key needs to implement a meaningful Equals() method, or you need an IEqualityComparer implementation that does the work for you. In this case I wouldn't bother with creating a new Key, just write an Equality Comparer that can compare two DataRows directly:

var duplicates = dataTable
        .AsEnumerable()
        .GroupBy(r => r, new MyDataRowComparer(keys))
        .Where(c => c.Count() > 1)
        .ToList();


internal class MyDataRowComparer : IEqualityComparer<DataRow>
{
    private readonly string[] _keys;

    public MyDataRowComparer(string[] keys)
    {
        _keys = keys; // keep the keys to compare by.
    }

    public bool Equals(DataRow x, DataRow y)
    {
        // a simple implementation that checks if all the required fields 
        // match. This might need more work.
        bool areEqual = true;
        foreach (var key in _keys)
        {
            areEqual &= (x[key] == y[key]);
        }
        return areEqual;
    }

    public int GetHashCode(DataRow obj)
    {
        // Add implementation here to create an aggregate hashcode.
    }
}    

这篇关于动态创建匿名对象从列表中的值C#的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆