【问题标题】:How to use CodeDom to generate inline dynamic methods?如何使用 CodeDom 生成内联动态方法?
【发布时间】:2015-04-20 22:00:16
【问题描述】:

我有一个 CodeMethodInvokeExpression,我希望将其用作 ()=><[function call]>

例如:Task.Run(()=><[My CodeMethodInvokeExpression]>).

为了清楚起见,CodeMethodInvokeExpression 可能非常复杂,例如调用带有 out 和 ref 参数的泛型方法,因此尝试编写解析它的东西可能非常复杂。

所以问题是:

  1. 可能有 CodeDom 的方式来做到这一点?
  2. 可能有一种 CodeDom 方法来获取 CodeMethodInvokeExpression 的字符串表示,因此我可以将其用作 CodeSnippetExpression。

【问题讨论】:

    标签: .net codedom codegen


    【解决方案1】:

    CodeDom 有点过时了。据我所知,您能做的最好的事情就是使用CodeSnippetExpression,但是当您拥有CodeMethodInvokeExpression 时,为时已晚——您实际上并没有关于您尝试调用的方法的信息,只是关于它的名称、对象和参数。更不用说它首先违背了使用 CodeDom 的目的。

    当然,您正在生成代码,因此您可以自己创建匿名方法,这就是编译器所做的。但同样,您需要比CodeMethodInvokeExpression 中获得的信息更多的信息。最后,你只是在兜圈子。

    另外,请注意out 是 C# 的专长——它实际上并不是 CLR 语言的共同点。在其他语言中,它可能与ref 相同。

    注意可以使用CodeDom生成代码sn-ps:

    var provider = new CSharpCodeProvider();
    
    using (var writer = new StringWriter())
    {
        provider.GenerateCodeFromExpression
            (
                new CodeMethodInvokeExpression
                (
                    new CodeMethodReferenceExpression
                    (
                        new CodeThisReferenceExpression(), 
                        "MyMethod", 
                        new CodeTypeReference(typeof(string))
                    ),
                    new CodeDirectionExpression(FieldDirection.Out, new CodeArgumentReferenceExpression("myArgument"))
                ),
                writer,
                null
            );
    
        writer.ToString().Dump();
    }
    

    此示例代码将生成以下内容:

    this.MyMethod(out myArgument)

    您可以从中创建一个CodeSnippetExpression,手动添加() =>,并使用该sn-p 作为您的方法的参数,以获取委托。同样,这仅适用于 C# - 您需要修改代码以使其在其他地方工作。

    【讨论】:

    • 谢谢,我看到了那个方法,但是在你写完之后,我决定使用它。但是你说 CodeDom 已经过时了。什么是较新的替代方案?
    • @YechielB.D.我不认为有任何明确的替代。但是,还有其他方法可以完成相同的任务; T4 模板在编译时生成代码非常流行,而表达式树在运行时生成(和编译)代码时非常有用。除了多语言支持之外,CodeDom 并没有真正给你太多 - 如果你不使用那部分,T4s(或其他模板生成器)更直接且更易于阅读。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-08
    • 2011-06-14
    • 1970-01-01
    • 1970-01-01
    • 2014-08-25
    • 1970-01-01
    相关资源
    最近更新 更多