internal Delegate ConvertToDelegate(Type clrDelegateType, IDelegateAdapter adapter) { Func <Delegate, Delegate> func; if (adapter is DummyDelegateAdapter) { DelegateAdapter.ThrowAdapterNotFound(adapter.Method); return(null); } if (clrDelegates.TryGetValue(clrDelegateType, out func)) { return(func(adapter.Delegate)); } else { throw new KeyNotFoundException("Cannot find convertor for " + clrDelegateType); } }
protected object ConvertToDelegate(object o, Type toType) { var toMethodInfo = toType.GetMethod("Invoke"); var toMethodParams = toMethodInfo.GetParameters(); var toMethodParamCount = toMethodParams.Length; MethodInfo fromMethod; object fromObject; FindMethod(o, toMethodParamCount, out fromObject, out fromMethod); // simplest case - when parameters are contravariant and result is covariant var toDelegate = Delegate.CreateDelegate(toType, fromObject, fromMethod, false); if (toDelegate != null) { return(toDelegate); } // use adapter with run-time types conversion var adapter = new DelegateAdapter(fromObject, fromMethod); foreach (var adapterMethod in adapter.GetType().GetMethods()) { if (adapterMethod.Name == "Invoke" && adapterMethod.GetParameters().Length == toMethodParamCount) { var resType = toMethodInfo.ReturnType != typeof(void) ? toMethodInfo.ReturnType : typeof(object); var genericTypes = new Type[toMethodParamCount + 1]; for (int i = 0; i < toMethodParams.Length; i++) { genericTypes[i] = toMethodParams[i].ParameterType; } genericTypes[toMethodParamCount] = resType; // last type for result var typedInvokeMethod = adapterMethod.MakeGenericMethod(genericTypes); LogManager.GetLogger(typeof(DelegateConverter)).Write(LogEvent.Info, typedInvokeMethod.ToString()); return(Delegate.CreateDelegate(toType, adapter, typedInvokeMethod, true)); } } throw new InvalidCastException(); }
internal Delegate ConvertToDelegate(Type clrDelegateType, IDelegateAdapter adapter) { Func <Delegate, Delegate> func; if (adapter is DummyDelegateAdapter) { DelegateAdapter.ThrowAdapterNotFound(adapter.Method); return(null); } if (clrDelegates.TryGetValue(clrDelegateType, out func)) { return(func(adapter.Delegate)); } else { StringBuilder sb = new StringBuilder(); string clsName, rName; bool isByRef; clrDelegateType.GetClassName(out clsName, out rName, out isByRef); sb.AppendLine("Cannot find convertor for " + rName); sb.AppendLine("Please add following code:"); sb.Append("appdomain.DelegateManager.RegisterDelegateConvertor<"); sb.Append(rName); sb.AppendLine(">((act) =>"); sb.AppendLine("{"); sb.Append(" return new "); sb.Append(rName); sb.Append("(("); var mi = clrDelegateType.GetMethod("Invoke"); bool first = true; foreach (var i in mi.GetParameters()) { if (first) { first = false; } else { sb.Append(", "); } sb.Append(i.Name); } sb.AppendLine(") =>"); sb.AppendLine(" {"); if (mi.ReturnType != appdomain.VoidType.TypeForCLR) { sb.Append(" return ((Func<"); first = true; foreach (var i in mi.GetParameters()) { if (first) { first = false; } else { sb.Append(", "); } i.ParameterType.GetClassName(out clsName, out rName, out isByRef); sb.Append(rName); } if (!first) { sb.Append(", "); } mi.ReturnType.GetClassName(out clsName, out rName, out isByRef); sb.Append(rName); } else { sb.Append(" ((Action<"); first = true; foreach (var i in mi.GetParameters()) { if (first) { first = false; } else { sb.Append(", "); } i.ParameterType.GetClassName(out clsName, out rName, out isByRef); sb.Append(rName); } } sb.Append(">)act)("); first = true; foreach (var i in mi.GetParameters()) { if (first) { first = false; } else { sb.Append(", "); } sb.Append(i.Name); } sb.AppendLine(");"); sb.AppendLine(" });"); sb.AppendLine("});"); throw new KeyNotFoundException(sb.ToString()); } }