Crear dinámicamente objeto anónimo a partir de valores de lista c #

Tengo una lista (o puede ser una matriz) de cadenas de las que quiero crear dinámicamente un objeto anónimo. ¿Cómo hago esto?

var dataSet = new DataSet(); dataSet.ReadXml(@""); var dataTable = dataSet.Tables[0]; var dataRow = dataTable.Rows[0]; var keys = new List {"Column1","Column2"}; var result = new {keys[0] = dataRow[keys[0]], keys[1] = dataRow[keys[1]]} 

Por lo tanto, esa lista llamada “claves” se creará fuera de este método y puede contener 1 a muchos valores. Intenté crear un diccionario y recorrer la lista y agregar pares clave / valor al diccionario, pero luego no pude descubrir cómo convertir el diccionario de nuevo a un tipo anónimo. También experimenté con los objetos de expansión, pero eso no parecía llevarme más lejos.

Debo poder devolver un tipo anónimo, ya que el resultado de este método se utilizará con la cláusula GroupBy de una consulta LINQ.

Aquí está el método que tuve para crear dinámicamente el diccionario:

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

Aquí está mi consulta LINQ:

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

La cláusula GroupBy funciona si codifico en un tipo anónimo desde el método Key (). Básicamente, solo necesito que la cláusula GroupBy se establezca dinámicamente en función de los valores en la lista de claves.

Al eliminar su pregunta, lo que desea es poder agrupar una lista de elementos en función de una propiedad de tiempo de ejecución que podría estar compuesta por una o más propiedades de ese elemento. En esencia, significa que necesita una función de selección (que es su método de Key ) que transforma un elemento en una clave.

Para que GroupBy funcione, debe poder comparar dos instancias de la clave para ver si son iguales. Esto significa que la clave necesita implementar un método Equals() significativo, o necesita una implementación de IEqualityComparer que haga el trabajo por usted. En este caso, no me molestaría en crear una nueva clave, simplemente escriba un Comparador de igualdad que pueda comparar dos DataRows directamente:

 var duplicates = dataTable .AsEnumerable() .GroupBy(r => r, new MyDataRowComparer(keys)) .Where(c => c.Count() > 1) .ToList(); internal class MyDataRowComparer : IEqualityComparer { 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. } }