今天我接到了一些舊的動態鑄造代碼此錯誤(我已經改變了最後一行,並留出了堆棧跟蹤的其餘部分):調用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