Сегодня я получил эту ошибку из некоторого старого кода динамического приведения (я изменил последнюю строку и пропустил остальную часть трассировки стека):
Item has already been added.
Key in dictionary:
'Int32 Count[Object](System.Collections.Generic.IEnumerable`1[System.Object])'
Key being added:
'Int32 Count[Object](System.Collections.Generic.IEnumerable`1[System.Object])'
---> System.ArgumentException: Item has already been added.
Key in dictionary:
'Int32 Count[Object](System.Collections.Generic.IEnumerable`1[System.Object])'
Key being added:
'Int32 Count[Object](System.Collections.Generic.IEnumerable`1[System.Object])'
at System.Reflection.CerHashtable`2.Insert(K[] keys, V[] values, Int32& count, K key, V value)
at System.Reflection.CerHashtable`2.Preallocate(Int32 count)
at System.RuntimeType.RuntimeTypeCache.GetGenericMethodInfo(RuntimeMethodHandle genericMethod)
at System.RuntimeType.GetMethodBase(RuntimeTypeHandle reflectedTypeHandle, RuntimeMethodHandle methodHandle)
at System.Reflection.RuntimeMethodInfo.MakeGenericMethod(Type[] methodInstantiation)
at MyNamespace.CommunicationExtensions.BuildMessage[T](T obj)
Полный класс
public static class CommunicationExtensions {
static readonly object lockobj = new object();
public static bool CanBuildMessage<T>(this T obj) where T: class {
return obj != null && (MessageFactory.MessageBuilders.ContainsKey(obj.GetType()));
}
public static string BuildMessage<T>(this T obj) {
lock (lockobj) {
Delegate d;
var type = obj.GetType();
if (MessageFactory.MessageBuilders.TryGetValue(type, out d)) {
var castMethod = typeof(CommunicationExtensions).GetMethod("Cast").MakeGenericMethod(type);
var castedObject = castMethod.Invoke(null, new object[] { obj });
return d.DynamicInvoke(castedObject) as string;
}
}
return null;
}
public static T Cast<T>(object o) {
return (T)o;
}
}
MessageFactory.MessageBuilders
- это Dictionary<Type,Func<Type,string>>
, содержащий скомпилированные лямбда-выражения, которые лениво создаются по мере необходимости для преобразования событий Message (простых классов авто-свойств на основе EventArgs) в строковый формат, используемый в других системах. Я не думаю, что все это имеет значение, хотя. Я думаю, что единственный код, необходимый для возникновения этой проблемы:
public static class CastError{
public static void GetCast<T>(this T obj) {
var type = obj.GetType();
var castMethod = typeof(CastError).GetMethod("Cast").MakeGenericMethod(type);
//...
}
public static T Cast<T>(object o) {
return (T)o;
}
}