我有一个应用程序,它接受外部应用程序的dll,查找指定的类和方法。然后它从这个外部方法中获取methodinfo,然后尝试通过Delegate.CreateDelegate创建一个委托。
我不断地
System.ArgumentException: 'Cannot bind to the target method because its signature or security transparency is not compatible with that of the delegate type.'我已经进行了一些提取代码,以使它更容易共享和调试,以及编写一个小的简单的外部应用程序来阅读。见下面的代码:
外部应用程序示例作为库(.Net Framework4.8)
using System;
namespace MethodLib
{
public class PrintText
{
public string Print(string textToPrint, int number)
{
return $"{ PrintPrivate(textToPrint) }: {number}";
}
public static string PrintStatic(string textToPrint)
{
return textToPrint;
}
public void PrintVoid(string textToPrint)
{
Console.WriteLine(textToPrint);
}
private string PrintPrivate(string textToPrint)
{
return $"This is { textToPrint }";
}
}
}应用程序到CreateDelegate
MethodInfo创建
using System;
using System.Reflection;
namespace DelegateApp
{
public class PluginSupport
{
public MethodInfo GetMethodInfo(string methodName, string externalLocation)
{
var instance = Activator.CreateInstance(Assembly.LoadFrom(externalLocation)
.GetType("MethodLib.PrintText"));
var methodInfo = instance.GetType()
.GetMethod(methodName, BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance);
return methodInfo;
}
}
}创建代理部件
namespace DelegateApp
{
public class MethodGenerator
{
private PluginSupport _pluginSupport;
public MethodGenerator()
{
_pluginSupport = new PluginSupport();
}
public MethodDetails Create(string methodName, string path)
{
var method = _pluginSupport.GetMethodInfo(methodName, path);
if (Equals(method, null))
{
throw new KeyNotFoundException($"Method '{ methodName }' doesn't exist in class");
}
return new MethodDetails
{
MethodName = method.Name,
ComponentName = method.DeclaringType.Name,
FriendlyName = method.DeclaringType.Name,
Parameters = method.GetParameters(),
LogicalPath = method.DeclaringType.Assembly.Location,
Method = (Func<string>)Delegate.CreateDelegate(typeof(Func<string>), method)
};
}
}
}我试过什么
所以读了很多不同的帖子我想我正在用的电话
(Func<string>)Delegate.CreateDelegate(typeof(Func<string>), method)实际上只适用于静态方法,而且由于我对所有公共方法感兴趣,所以我缺少了一个目标/实例。
因此,从其他示例中,您需要创建实例并将其传递到其中,因此我使用了var myInstance = Actovator.CreateInstance,然后也传递了这个变量,结果如下所示
(Func<string>)Delegate.CreateDelegate(typeof(Func<string>), myInstance, method)
我也试过用这个
public static Delegate CreateDelegate(Type type, Type target, string method, bool ignoreCase);
所有这一切都在不断地
System.ArgumentException: 'Cannot bind to the target method because its signature or security transparency is not compatible with that of the delegate type.'我唯一能让它发挥作用的时候,是我做以下事情的时候:
来自外部应用程序的methodName = PrintStatic
var methodInfo = instance.GetType()
.GetMethod(methodName, BindingFlags.Public | BindingFlags.Static);
var deleg = (Func<string>)Delegate.CreateDelegate(typeof(Func<string>),null, method)当然,这不是我想要的,因为这只对我来说是静态的,我也要非静态的。但是即使这样,如果我将BindingFlags.Instance添加到混合中,静态也会抛出相同的错误。
如果我还删除了BindingFlags.Instance和methodName = Print,那么methodInfo是null。
我的问题
关于Delegate.CreateDelegate
BindingFlags.Instance,就不给我公开的非静态成员呢?发布于 2021-02-11 21:32:55
多亏了@Charlieface,我才意识到我的签名类型与创建委托不相对应。
因此,在这个示例代码中,我最终得到的结果是在MethodGenerator类中执行以下操作
parameters H 112的params数量,检查是否有方法isstatic,并据此将其设置为H 214G 215
methHead = method.IsStatic
? Delegate.CreateDelegate(delegateFunc.MakeGenericType(types.ToArray()), null, method)
: Delegate.CreateDelegate(delegateFunc.MakeGenericType(types.ToArray()), instance, method); 我猜这是一些复杂的代码,但是它可以工作,并且需要对它进行改进,或者将它放到我们想要使用的实际代码库中。但正如@Charlieface提到的,if you don't know the type, there isn't much point to the delegate.
最后一段代码
public MethodDetails Create(string methodName, string path)
{
var method = _pluginSupport.GetMethodInfo(methodName, path);
if (Equals(method, null))
{
throw new KeyNotFoundException($"Method '{ methodName }' doesn't exist in class");
}
var instance = Activator.CreateInstance(method.DeclaringType);
List<Type> types = new List<Type>();
var methodPrams = method.GetParameters();
foreach (var item in methodPrams)
{
types.Add(Type.GetType(item.ParameterType.UnderlyingSystemType.FullName));
}
var funcType = typeof(Func<>);
var delegateFunc = Type.GetType(funcType.FullName.Replace("1", (methodPrams.Length + 1).ToString()));
Delegate methHead;
types.Add(typeof(string));
methHead = method.IsStatic
? Delegate.CreateDelegate(delegateFunc.MakeGenericType(types.ToArray()), null, method)
: Delegate.CreateDelegate(delegateFunc.MakeGenericType(types.ToArray()), instance, method);
return new MethodDetails
{
MethodName = method.Name,
ComponentName = method.DeclaringType.Name,
FriendlyName = method.DeclaringType.Name,
Parameters = method.GetParameters(),
LogicalPath = method.DeclaringType.Assembly.Location,
Method = methHead
};
}https://stackoverflow.com/questions/66157420
复制相似问题