- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
我需要一个方法,它采用一个 MethodInfo
实例来表示具有任意签名的非泛型静态方法,并返回一个绑定(bind)到该方法的委托(delegate),该委托(delegate)稍后可以使用 Delegate.DynamicInvoke< 调用
方法。我的第一个天真的尝试是这样的:
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
方法可以自己找出正确的委托(delegate)类型。好吧,显然不能。那么,如何创建一个 System.Type
实例来表示一个签名与所提供的 MethodInfo
实例相匹配的委托(delegate)?
最佳答案
您可以使用 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
的参数是一种很好的风格。
如果您想拒绝所有泛型方法,请使用 method.IsGenericMethod
;如果您只想拒绝具有未替换类型参数的泛型方法,请使用 method.ContainsGenericParameters
。
关于c# - 当无法事先知道方法签名时,如何从 MethodInfo 创建委托(delegate)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16364198/
嘿,我有一个任意的 SQL 查询。从这个查询开始,我想知道这个查询将访问或更改哪些表。可能定义了一些函数或触发器,这些函数或触发器还会更改查询中声明的表之外的其他表。 我考虑过创建一个不同的 mysq
我是一名优秀的程序员,十分优秀!