anonymous-objects declare - C'è un modo semplice per unire gli oggetti anonimi C#




type how (4)

Diciamo che ho due oggetti anonimi come questo:

var objA = new { test = "test", blah = "blah" };
var objB = new { foo = "foo", bar = "bar" };

Voglio combinarli per ottenere:

new { test = "test", blah = "blah", foo = "foo", bar = "bar" };

Non saprò quali siano le proprietà per objA e objB in fase di compilazione. Voglio che questo sia come il metodo di estensione di jquery.

Qualcuno sa di una libreria o di una classe .net framework che può aiutarmi a fare questo?


Answers

Se vuoi veramente dire dinamico nel senso C # 4.0, allora puoi fare qualcosa come:

static dynamic Combine(dynamic item1, dynamic item2)
{
    var dictionary1 = (IDictionary<string, object>)item1;
    var dictionary2 = (IDictionary<string, object>)item2;
    var result = new ExpandoObject();
    var d = result as IDictionary<string, object>; //work with the Expando as a Dictionary

    foreach (var pair in dictionary1.Concat(dictionary2))
    {
        d[pair.Key] = pair.Value;
    }

    return result;
}

Potresti anche scrivere una versione usando il reflection che prende due oggetti (non dinamici) e restituisce una dinamica.


Utilizzando TypeDescriptor

Come menzionato nei commenti, la soluzione di Luke Foust non funziona con i tipi anonimi. Il cast del dizionario non funziona, propongo di costruire i dizionari usando il metodo TypeDescriptor.GetProperties :

public static dynamic CombineDynamics(object object1, object object2)
{
  IDictionary<string, object> dictionary1 = GetKeyValueMap(object1);
  IDictionary<string, object> dictionary2 = GetKeyValueMap(object2);

  var result = new ExpandoObject();

  var d = result as IDictionary<string, object>;
  foreach (var pair in dictionary1.Concat(dictionary2))
  {
    d[pair.Key] = pair.Value;
  }

  return result;
}

private static IDictionary<string, object> GetKeyValueMap(object values)
{
  if (values == null)
  {
    return new Dictionary<string, object>();
  }

  var map = values as IDictionary<string, object>;
  if (map == null)
  {
    return map;
  }

  map = new Dictionary<string, object>();
  foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(values))
  {
    map.Add(descriptor.Name, descriptor.GetValue(values));
  }

  return map;
}

Funziona ora con tipi anonimi:

var a = new {foo = "foo"};
var b = new {bar = "bar"};

var c = CombineDynamics(a, b);

string foobar = c.foo + c.bar;

Gli appunti:

Il mio metodo GetKeyValueMap è basato sulla classe RouteValueDictionary (System.Web.Routing). L'ho riscritto (usando ILSpy per disassemblarlo) perché penso che una classe System.Web non abbia nulla a che fare con l'unione degli oggetti.


Ho provato unire due oggetti in un tipo anonimo di Kyle Finley e funziona perfettamente.

Con TypeMerger la fusione è semplice come

var obj1 = new {foo = "foo"};

var obj2 = new {bar = "bar"};

var mergedObject = TypeMerger.MergeTypes(obj1 , obj2 );

È così che hai ottenuto l'oggetto unito, a parte quello, c'è una disposizione per ignorare anche le proprietà specifiche.


Da CLR via C # :

Durante la normalizzazione delle stringhe, si consiglia vivamente di utilizzare ToUpperInvariant anziché ToLowerInvariant poiché Microsoft ha ottimizzato il codice per l'esecuzione di confronti maiuscoli .

Ricordo che una volta il mio collega ha sempre modificato le stringhe in maiuscolo prima di confrontarle. Mi sono sempre chiesto perché lo fa perché ritengo sia più "naturale" convertire prima in lettere minuscole. Dopo aver letto il libro ora so perché.





c# anonymous-objects