c# - C#:通过反射将通用多播委托分配给具有不同数量参数的操作
问题描述
因此,在我的班级中,一些代表都是 Action<...> 字段。例子:
public Action<int> onDiceRolled;
public Action<Turn, Round> onTurnEnded;
我想使用反射为他们每个人分配一个匿名函数。
GetType().GetFields()
.Where(field => field.FieldType.ToString().Contains("Action"))
.ToList()
.ForEach(field =>
{
Type type = field.FieldType; // e.g. Action<Turn, Round>
if (!type.IsGenericType)
return;
Type[] para = type.GetGenericArguments(); // in example cases: {int} or {Turn, Round}
MethodInfo debugMethod = (new Action(() => Console.WriteLine(field.Name + " was called."))).Method;
field.SetValue(this, Delegate.CreateDelegate(type, debugMethod));
});
当然这不起作用,因为创建的委托没有任何参数,而它需要的参数存储在 para. 不幸的是,我找不到通过类型数组创建委托的任何方法。
所以基本上我想做
onDiceRolled += (i) => Console.WriteLine("onDiceRolled was called.");
对于我班上的每个行动领域
解决方案
要设置委托,您可以使用表达式树来编译一个:
GetType().GetFields()
.Where(field => field.FieldType.ToString().Contains("Action"))
.ToList()
.ForEach(field =>
{
Type type = field.FieldType; // e.g. Action<Turn, Round>
if (!type.IsGenericType)
return;
Type[] para = type.GetGenericArguments(); // in example cases: {int} or {Turn, Round}
Expression<Action> x = () => Console.WriteLine(field.Name + " was called.");
var action = Expression.Lambda(x.Body, para.Select(p => Expression.Parameter(p))).Compile();
field.SetValue(this, action);
});
推荐阅读
- javascript - 生成 powerpoint 时使用 RED X 代替图像
- python - 我想做出随机选择,但它的值有权重
- amazon-ecs - 如何在 CodePipeline 中处理 ECS 部署以更改任务定义
- python - 即使已安装,也无法在 jupyter notebbok 中导入 numpy 库
- python - 所需给定功能的说明
- javascript - CEFSharp Dropdown(组合框,选择)向下打开超过浏览器边缘并被剪裁
- ios - 为什么 UIActivityViewController 会在 Presenter 上调用 viewWillDisappear()?
- spring-boot - MDCFilter 和 Spring webflux 使用 reactor netty 和 spring security oauth
- regex - 在 Regex 中第一次出现时停止
- xamarin - 如何从 xamarin android web 视图中加载的登录页面的用户名文本框中读取值