Gesonderte Erklärung und Erstellung von Wörterbuch mit anonymen Schlüssel

StackOverflow https://stackoverflow.com/questions/1434782

  •  07-07-2019
  •  | 
  •  

Frage

In meinem Code, den ich eine Reihe von Lookup-Tabellen zu erstellen.

var Dict1 = data1.ToDictionary(dim => new { dim.Val1,dim.Val2,.. }  );
var Dict2 = data2.ToDictionary(dim => new { dim.Val1,dim.Val2,.. }  );

irgendwann gibt es doppelte Schlüsselwerte, also versuchte ich einen catch-Block zu verwenden,

try
{
   var Dict1 = data1.ToDictionary(dim => new { dim.Val1,dim.Val2,.. }  );
}
catch (ArgumentException ex)
{
    Console.WriteLine("Duplicate values in Data1 {0}",ex);
    throw;
}

aber dieser Ansatz bedeutet, dass die Dicts nicht auf den Rest des Codes sichtbar sein.

Alle Ideen, wie dies zu tun?

Edit:. Die Absicht des catch-Block ist die Wörterbucherstellung fehlgeschlagen melden

War es hilfreich?

Lösung

Deklarieren und ein einzelnes Element über dem Versuch hinzufügen, und dann den Rest nach innen addieren. Da Sie speziell besorgt über doppelte Schlüssel sind, Hinzufügen des ersten Schlüssels / item erhält man die Art, ohne das Risiko.

EDIT: Ich denke nur, die Art Folgern, ohne das erste Element hinzugefügt wird, ist etwas besser. Während die Nutzung etwas umständlich ist, wird es erleichtern übrigen Elemente hinzuzufügen (im Gegensatz zu Löschen des Wörterbuch dagegen, und dann Zugabe - oder mit alles nach dem ersten ein bis hinzufügen - wirklich nur sauber machbar, wenn Sie eine sind raubend IEnumerable).

var dict1 = InferDictionary(new { Value1 = 0, Value2 = "string" }, new DataItem());
try {
  data1.AddToDictionary(
     dict1, 
     dim => new { Value1 = dim.Val1, Value2 = dim.Val2 }
  );
} catch ... {
    ...
}

static IDictionary<TKey, TValue> InferDictionary<TKey, TValue>(TKey keyPrototype, TValue valuePrototype) {
    return new Dictionary<TKey, TValue>();
}

Oder erstellen Sie eine Komfortfunktion, die Ausnahme für Sie zu fangen:

var dict1 = TryCatch(
  () => 
      data1.ToDictionary(dim => new { 
         Value1 = dim.Val1,
         Value2 = dum.Val2
      }
  , (ArgumentException ex) => {
      Console.WriteLine("Duplicate values in Data1 {0}", ex);
     // throw(ex) works as well, and shouldn't screw the callstack up much
     // But I happen to like making it explicit
     return false; 
  }
);

static TResult TryCatch<TResult, TException>(Func<TResult> @try, Func<TException, bool> @catch) where TException : Exception {
   try {
       return @try();
   } catch (Exception ex) {
       TException tEx = ex as TException;
       if (tEx != null && @catch(ex)) {
          // handled
       } else {
          throw;
       } 
   }
}

Der Nachteil dabei ist, dass Sie nicht TryCatch<,> in die „natürliche“ Weise nennen kann:

// Not enough info to infer TException
var d = TryCatch(() => DoStuff(), ex => true);

// Can't infer only TResult
var d = TryCatch<ArgumentException>(() => DoStuff(), ex => true);

, die, da Sie nicht TResult angeben können, zwingt Sie in die etwas seltsame Syntax von TException auf der Lambda-Deklaration:

var d = TryCatch(() => DoStuff(), (ArgumentException ex) => true);

Andere Tipps

Sie konnten die Dict1 Variable außerhalb des Try-Catch-Block deklarieren.

Gibt es einen Grund, den try/catch Block zu benutzen? Sie fügen keinen Wert zu Ihrem Programm neben an die Konsole zu schreiben. Wenn Sie dort aktuelle Fehlerbehandlung zu tun wurden, konnte ich dieses Problem sehen zu lösen, aber ich würde nur die Ausnahme geschehen lassen und nicht versuchen, sie zu fangen überhaupt.

Du wirst viel Aufwand zu vermeiden, eine neue Art zu erklären. Anonyme Typen sind eine Funktion, wenn Sie ein sehr spezifischen Daten Konstrukt haben, die Sie erwarten, nie wieder an einem anderen Ort in Ihrem Code zu verwenden. In diesem Fall sollten Sie die gleiche Art in mehr als ein Ort vertreten, so dass die beste Lösung wahrscheinlich ist es, einfach eine Klasse zu erstellen, die Art darzustellen. Sie können es eine private verschachtelte Klasse machen Ihre Art Raum zu vermeiden, außerhalb dieser Klasse zu verschmutzen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top