How to create a delegate from a MethodInfo when method signature cannot be known beforehand?(当事先无法知道方法签名时,如何从 MethodInfo 创建委托?)
问题描述
我需要一个方法,它接受一个 MethodInfo
实例,该实例表示具有任意签名的非泛型静态方法,并返回一个绑定到该方法的委托,以后可以使用 Delegate.DynamicInvoke代码>方法.我的第一次天真的尝试是这样的:
I need a method that takes a MethodInfo
instance representing a non-generic static method with arbitrary signature and returns a delegate bound to that method that could later be invoked using Delegate.DynamicInvoke
method. My first naïve try looked like this:
using System;
using System.Reflection;
class Program
{
static void Main()
{
var method = CreateDelegate(typeof (Console).GetMethod("WriteLine", new[] {typeof (string)}));
method.DynamicInvoke("Hello world");
}
static Delegate CreateDelegate(MethodInfo method)
{
if (method == null)
{
throw new ArgumentNullException("method");
}
if (!method.IsStatic)
{
throw new ArgumentNullException("method", "The provided method is not static.");
}
if (method.ContainsGenericParameters)
{
throw new ArgumentException("The provided method contains unassigned generic type parameters.");
}
return method.CreateDelegate(typeof(Delegate)); // This does not work: System.ArgumentException: Type must derive from Delegate.
}
}
我希望 MethodInfo.CreateDelegate
方法本身可以找出正确的委托类型.好吧,显然它不能.那么,如何创建一个 System.Type
的实例来表示具有与提供的 MethodInfo
实例匹配的签名的委托?
I hoped that the MethodInfo.CreateDelegate
method could figure out the correct delegate type itself. Well, obviously it cannot. So, how do I create an instance of System.Type
representing a delegate with a signature matching the provided MethodInfo
instance?
推荐答案
你可以使用System.Linq.Expressions.Expression.GetDelegateType 方法:
using System;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
class Program
{
static void Main()
{
var writeLine = CreateDelegate(typeof(Console).GetMethod("WriteLine", new[] { typeof(string) }));
writeLine.DynamicInvoke("Hello world");
var readLine = CreateDelegate(typeof(Console).GetMethod("ReadLine", Type.EmptyTypes));
writeLine.DynamicInvoke(readLine.DynamicInvoke());
}
static Delegate CreateDelegate(MethodInfo method)
{
if (method == null)
{
throw new ArgumentNullException("method");
}
if (!method.IsStatic)
{
throw new ArgumentException("The provided method must be static.", "method");
}
if (method.IsGenericMethod)
{
throw new ArgumentException("The provided method must not be generic.", "method");
}
return method.CreateDelegate(Expression.GetDelegateType(
(from parameter in method.GetParameters() select parameter.ParameterType)
.Concat(new[] { method.ReturnType })
.ToArray()));
}
}
在第二次检查 !method.IsStatic
时可能存在复制粘贴错误 - 您不应在此处使用 ArgumentNullException
.将参数名称作为参数提供给 ArgumentException
是一种很好的风格.
There is probably a copy-paste error in the 2nd check for !method.IsStatic
- you shouldn't use ArgumentNullException
there. And it is a good style to provide a parameter name as an argument to ArgumentException
.
如果您想拒绝所有泛型方法,请使用 method.IsGenericMethod
,如果您只想拒绝具有未替换类型参数的泛型方法,请使用 method.ContainsGenericParameters
.
Use method.IsGenericMethod
if you want to reject all generic methods and method.ContainsGenericParameters
if you want to reject only generic methods having unsubstituted type parameters.
这篇关于当事先无法知道方法签名时,如何从 MethodInfo 创建委托?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:当事先无法知道方法签名时,如何从 MethodInfo 创建委托?


- C# 中多线程网络服务器的模式 2022-01-01
- MoreLinq maxBy vs LINQ max + where 2022-01-01
- 带有服务/守护程序应用程序的 Microsoft Graph CSharp SDK 和 OneDrive for Business - 配额方面返回 null 2022-01-01
- 良好实践:如何重用 .csproj 和 .sln 文件来为 CI 创建 2022-01-01
- Web Api 中的 Swagger .netcore 3.1,使用 swagger UI 设置日期时间格式 2022-01-01
- 如何用自己压缩一个 IEnumerable 2022-01-01
- WebMatrix WebSecurity PasswordSalt 2022-01-01
- 在哪里可以找到使用中的C#/XML文档注释的好例子? 2022-01-01
- 输入按键事件处理程序 2022-01-01
- C#MongoDB使用Builders查找派生对象 2022-09-04