如何发出委托或 lambda 表达式

2023-12-01

我想发出一个返回 Function 的方法。在这个方法中,我必须创建一个委托或一个正好服务于返回类型的 lambda 表达式。

总的来说,它应该看起来像这样:

// I have a resolve method that will be called inside my missing method
// This is it's signature:
object Resolve( params object[] args);

// This is how I use it:
var barFactory = ( Func<IBar> )MissingMethod( typeof( IBar ) );
var bar = barFactory.Invoke();

// or - with one string argument:
var fooFactory = ( Func<string, IFoo> )MissingMethod( typeof( IFoo ), typeof( string ) );
var foo = fooFactory.Invoke( "argument for foo" );

在 Missing Method() 中,它应该如下所示:

object MissingMethod( Type returnType, params Type[] argTypes )
{
  // Create the type of Func<> based on the passed returnType and the argTypes
  var funcType = typeof(Func<,...,>).MakeGenericType( ... )

  // Here I have to use the Resolve() method and cast the lambda to the correct type
  return (cast to funcType)( (arg1, arg2) => Resolve( arg1, arg2 ) );
}

我认为获得 MissingMethod() 的唯一方法是使用 Reflection.emit。

您知道有关发出 lambda 或委托的优质资源或教程吗?

您是否看到此问题的另一种可能的解决方案?

EDIT:
这是我想要实现的场景:

static void Main()
{
  var container = new Container();
  container.Register<Foo>();
  container.Register<ConsumerClass>();

  var consumerClass = Container.Resolve<ConsumerClass>();
}

class Foo()
{
  public Foo( string argument ) {}
}

class ConsumerClass
{
  public ConsumerClass( [Inject] Func<string, Foo> factory )
  {
    var foo1 = factory.Invoke( "first foo" );
    var foo2 = factory.Invoke( "another foo" );
    // ...
  }
}

我正在尝试实现 Container 和 Resolve() 方法。我知道注册了一个“Foo”类型。我知道它的构造函数需要一个字符串来调用。

当我必须解析类型“ConsumerClass”时,我发现它想要注入一个 Func 。这并不完全是我的容器可以提供的,因为通常它为 Foo 提供单个实例,如下所示:

Container.Resolve<Foo>( "argument" );

但尽管如此,容器也应该能够提供 Func。它具有所需的所有信息。

但现在我陷入了创建这个绑定 Func 的困境。请记住,它也可以是 Func。因此,我正在寻找一种可以动态创建我的代表的解决方案。它们必须可转换为精确的绑定类型。

EDIT:
我不知道如何更好地描述它......我正在尝试做类似的事情this。但我不想通过一个目标。代替

delegate void object LateBoundMethod( object target, object[] arguments );

我的代表应该看起来像

delegate void object LateBoundMethod( object[] arguments );

并且目标作为实例字段提供。通过采用并“改进”Marc 的解决方案,我得到:

private Delegate CreateDelegate( Type returnType, Type[] parameterTypes )
{
  m_Type = returnType;

  var i = 0;
  var param = Array.ConvertAll( parameterTypes, arg => Expression.Parameter( arg, "arg" + i++ ) );
  var asObj = Array.ConvertAll( param, p => Expression.Convert( p, typeof( object ) ) );
  var argsArray = Expression.NewArrayInit( typeof( object ), asObj );

  var callEx = Expression.Call( null, typeof( FuncFactory ).GetMethod( "Resolve" ), argsArray );
  var body = Expression.Convert( callEx, returnType );

  var ret = Expression.Lambda( body, param ).Compile();
  return ret;
}

private readonly Container m_Container;
private Type m_Type;

public object Resolve( params object[] args )
{
  return m_Container.Resolve( m_Type, args );
}

但这是不完整的。 Resolve() 方法不再是静态的(因为它需要两个实例字段)并且无法被调用。所以这里的问题是

var callEx = Expression.Call( null, typeof( FuncFactory ).GetMethod( "Resolve" ), argsArray );

我认为我需要引用“this”,而不是传递 null 作为第一个参数。我怎么做?


第一个问题是Func<...>不存在 - 你需要编码Func<>, Func<,>, Func<,,>, Func<,,,>分别地。

现在;我理解代码,但我不确定您要解决的场景是什么......您能澄清一下吗?可能有更好的选择...

如果它像听起来那么复杂,那么定制Expression可能是最合适的选择(比Reflection.Emit).


这有效,例如...

static Delegate MissingFunc(Type result, params Type[] args)
{
    int i = 0;
    var param = Array.ConvertAll(args,
        arg => Expression.Parameter(arg, "arg" + i++));
    var asObj = Array.ConvertAll(param,
        p => Expression.Convert(p, typeof(object)));
    var argsArray = Expression.NewArrayInit(typeof(object), asObj);
    var body = Expression.Convert(Expression.Call(
                null, typeof(Program).GetMethod("Resolve"),
                argsArray), result);
    return Expression.Lambda(body, param).Compile();
}
static void Main()
{
    var func2 = MissingFunc(typeof(string), typeof(int), typeof(float));
}
public static object Resolve( params object[] args) {
    throw new NotImplementedException();
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何发出委托或 lambda 表达式 的相关文章

随机推荐

  • 我可以根据 firebase firestore 中对象的长度对结果进行排序吗?

    我的 firestore 文档中有一个投票字段 其中存储了对该文档进行投票的人员的 uid 我想调用所有文件并按照投票对象中的票数排序 I tried db collection myCollection orderBy Object ke
  • 合并两个不同维度的数组 PHP

    我有两个不同的维度数组 Array 1 Array1 0 gt Array id gt 123 price gt 5 purchase time gt 2014 4 10 1 gt Array id gt 123 price gt 5 pu
  • 尝试使用 javascript、jquery 和 html 搜索 wunderground 位置

    下面的代码不起作用 尝试搜索天气位置 当我搜索时什么也没有发生
  • Excel-VBA - 在数据字段数组中插入新的第一列,无需循环或 API 调用

    Intro 去年 PrzemyslawRemin 提出了这个问题如何在VBA中向现有矩阵添加计数器列 无需额外的循环 and 无需修改工作表 本示例中的原始矩阵是一个 基于 1 的 2 维 数据字段数组 源单元格仅包含其地址字符串 插入的行
  • 带回“覆盖”窗口方法[重复]

    这个问题在这里已经有答案了 如果我将 window alert 重置为其他功能 有什么方法可以恢复它而无需先 保存 它 例如 window alert function 这样做之后 有没有办法将 window alert 恢复到原来的状态
  • 将静态库转换为共享库?

    我有一个第三方库 主要由大量静态 a 库文件 我可以将其编译成一个 a库文件 但我真的需要它是一个单一的 so共享库文件 有什么方法可以将静态转换为 a文件到共享 so文件 或者更一般地说 是否有一个好的方法来组合大量的静态 a文件有几个
  • 在 Django 框架中发出 ajax Post 请求时出现 403 Forbidden 错误

    我正在尝试将 jquery 集成到我使用 Django 框架制作的 Web 应用程序中 然而我很难尝试做一个简单的ajax打电话去上班 我的模板文件包含用于处理 ajax 调用的 html 和 javascript 表单 如下所示
  • iPhone:在应用程序中同时使用 OpenGL 和本机用户界面的最佳方式是什么?

    我对 iPhone 平台还很陌生 所以我想知道在 OpenGL 渲染和 UIView 之间切换的最佳方式是什么 任何评论都非常感谢 根本不需要切换模式 iPhone 上的 OpenGL ES 渲染是在 CAEAGLLayer 核心动画层中完
  • 如何将一张表与许多不同的表关联起来?

    我有一个表格列表 即学生 教师 员工 部门 等等 每个表都有特定的注释 现在 表中的一条记录可以有一个或多个注释 这表明从任何表到注释表都是一对多关系 我不知道将评论表与其中每一个相关联的最佳方法是什么 如果我将评论表中的外键放入每个表中
  • 如何绘制堆积事件持续时间(甘特图)

    我有一个 Pandas DataFrame 其中包含流量计开始测量流量的日期以及该站退役的日期 我想生成一个以图形方式显示这些日期的图 这是我的数据框的示例 import pandas as pd data index 40623 4063
  • 将团队构建输出文件夹中的文件包含到 XAP 中

    我正在尝试使用 TFS 2010 对 Windows Phone 7 1 项目进行持续集成 有2个资源项目 用于本地化的 Win32 项目 和主要的 Windows Phone 项目 我已将上述 2 个项目的项目输出复制到主 WP 项目中的
  • Docker 堆栈在 Windows 中部署

    我在 docker stack windows 中有一些问题 我们可以在Windows 2016中启用docker stack吗 是否完全支持 如果是 我们如何启用 我们如何使用此文件自动创建 swarm 集群 我搜索过 google 但找
  • 服务器作曲家安装 --no-dev 被杀死

    当我尝试更新包时在服务器中 composer install no dev 结果是 我该如何修复它 看起来像composer install正在尝试更新软件包 因此您可能没有composer lock文件在你的项目中 在这种情况下compo
  • CFDictionary 获取 Swift3 中键的值

    我在访问 CFDictionary 中的特定 或任何 键时遇到问题 老实说 我真的不明白你需要在 Swift 中执行此操作的方式 而且我认为它过于复杂 My Code if let session DASessionCreate kCFAl
  • Jetpack Compose - 使 LazyRow 中的第一个元素与屏幕中心对齐

    我想获得一个LazyRow看起来像这样 aaa b bb cccc dd w x 是一屏宽度 元素的大小各不相同 但它们之间的间距是固定的 我想我可以添加一些开始内容填充LazyRow以便 aaa 可组合项与屏幕中心对齐 但我不知道它的宽度
  • 带空格的 Bash 变量

    我在 Windows 下的 MinGW shell 中面临下一个问题 我在我的 etc profile表达方式 export GIT SSH c Program Files TortoiseGit bin TortoisePlink exe
  • PowerPoint 和 WPF

    我确实需要一种在我的 wpf 应用程序中加载 ppt 文档的方法 谁能给我一个提示 代码示例 结帐下列的讨论线程 Dr WPF 还发表了一篇有趣的文章 可能对您也有帮助 WPF 应用程序中的托管 Office但是 考虑到您的场景的许可证成本
  • 如果是在生产环境中,调试死锁问题的正确行动计划是什么?

    注意我不是在问死锁的概念 我感兴趣的是如果你在生产集群服务器的java应用程序中遇到这个问题你会怎么做以及调试技巧 Question 关于分析步骤的计划的最佳实践 假设 您已经知道一台服务器受到此问题的影响 操作系统使用Linux Goal
  • 为什么属性不自动合成

    也许这是一个愚蠢的问题 每次我做一个 property我必须 synthesize它 但这毫无意义 你唯一能做的就是 property whatever Type property就是要做 synthesize property在实施文件中
  • 如何发出委托或 lambda 表达式

    我想发出一个返回 Function 的方法 在这个方法中 我必须创建一个委托或一个正好服务于返回类型的 lambda 表达式 总的来说 它应该看起来像这样 I have a resolve method that will be calle