Déclarez et ajoutez un seul élément au-dessus de l'essai, puis ajoutez le reste à l'intérieur. Puisque vous êtes spécifiquement préoccupé par les clés en double, l'ajout de la première clé/élément vous permet d'obtenir le type sans risque.
EDIT: Je pense que inférer le type, sans ajouter le premier élément, est légèrement meilleur. Bien que l'utilisation soit un peu lourde, il vous sera plus facile d'ajouter des éléments restants (par opposition à l'effacement du dictionnaire, puis d'ajouter - ou d'ajouter tout ce qui suit le premier - uniquement si vous consommez un 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>();
}
Ou, créer une fonction pratique pour intercepter l'exception pour vous:
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;
}
}
}
La mise en garde est que vous ne pouvez pas appeler TryCatch<,>
dans les voies « naturelles »:
// Not enough info to infer TException
var d = TryCatch(() => DoStuff(), ex => true);
// Can't infer only TResult
var d = TryCatch<ArgumentException>(() => DoStuff(), ex => true);
Ce qui, puisque vous ne pouvez pas spécifier
TResult
, vous oblige dans la syntaxe quelque peu étrange de déclarer
TException
sur le lambda:
var d = TryCatch(() => DoStuff(), (ArgumentException ex) => true);
Le premier exemple est-il compilé? Je reçois "Un type anonyme ne peut pas avoir plusieurs propriétés avec le même nom" et beaucoup de "Déclarant de membre de type anonyme non valide.Les membres de type anonyme doivent être déclarés avec une affectation de membre, un nom simple ou un accès membre." – dtb
Il compile avec le code réel, mais le code ci-dessus a été assaini –