今日は(私は最後の行を変更したとスタックトレースの残りのうち左)いくつかの古いダイナミックキャストのコードから、このエラーを得た: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>>
は、メッセージイベント(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はスレッドセーフであると文書化されています。このマルチスレッドコードですか? –
ええ、そこのDynamicInvokeは、必ずしもスレッドセーフではない何かを呼びます(変換されるクラスのgetメソッドは何でもできます)。 –
@BillBarry thats trueですが、スタックトレースはMakeGenericMethod呼び出しからのこのエラーを明示的に示しています... –