今天我接到了一些旧的动态铸造代码此错误(我已经改变了最后一行,并留出了堆栈跟踪的其余部分):调用MethodInfo.MakeGenericMethod时,这个关键错误意味着什么?
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>>
包含编译的lambda表达式,它们是根据需要构建的,以便将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;
}
}
哇,这是丑陋的。看起来像一个框架错误给我。 MethodInfo被记录为线程安全的。这是多线程代码? – 2012-02-23 19:09:00
是的,DynamicInvoke在那里调用一些不一定线程安全的东西,虽然(被转换的类的get方法可以做任何事情)。 – 2012-02-23 19:13:09
@BillBarry那是真的,但堆栈跟踪显式地显示来自MakeGenericMethod调用的这个错误... – 2012-02-23 19:14:59