繁体   English   中英

如何用反射识别lambda闭包

[英]How to identify a lambda closure with reflection

我正在编写一个涉及Actions的组件,当Action.Target对象是编译器生成的闭包时,它就要求找到一种使用反射案例进行标识的方法。 我正在做一个实验,试图找到一种方法,这个小实验的目的是开发一个带Action的谓词,并返回一个布尔值,该布尔值告诉action目标是否是此类闭包类的实例。

在我的测试案例中,我具有以下创建4种不同类型的动作的方法:

    private void _createClosure(int i)
    {
        ClosureAction = new Action(() =>
        {
            var j = i;
            var k = somenum;
        });
    }

    private void _createLambda()
    {
        LambdaAction = new Action(() =>
        {
            this._instanceAction();

        });
    }

    private void _createInstance()
    {
        InstanceAction = new Action(_instanceAction);
    }

    private void _createStatic()
    {
        StaticAction = new Action(_staticAction);
    }

    private int somenum;

    private void _instanceAction()
    {
        somenum++;
    }

    private static void _staticAction()
    {

    }

下表显示了每个操作的属性: 动作属性

如您所见,LambaAction和ClosureAction在定义方面非常相似,它们都使用lambda,但是闭包一个具有在lambda内部使用的局部函数变量,因此编译器被迫生成闭包类。 很明显,第二行,即呈现ClosureAction的行,是唯一具有闭包类型目标的行。 静态的一个根本没有目标,而另外两个则使用调用类(Called ActionReferences)作为目标。 下表提供了目标反射类型属性的比较: 目标类型

因此,我们可以看到闭包情况的独特之处在于目标类型不是类型信息,而是嵌套类型。 它也是唯一一个私有嵌套,密封且名称包含字符串+ <> c__DisplayClass的名称。 现在,尽管我认为这些特征对于任何正常使用情况都是决定性的,但我还是希望定义一个我可以依靠的谓词。 我不希望这种机制基于编译器的命名约定或不唯一的属性,因为从技术上讲,用户可能会创建具有相同命名约定的私有嵌套密封类……这不太可能,但这并不是100%干净的解决方案。

所以最后-问题是这样的:是否有一种干净的方法来编写谓词,这些谓词实际上是编译器生成的闭包的identify操作?

谢谢

这不是100%准确,但通常可以:

bool isClosure = action.Target != null && Attribute.IsDefined(
    action.Target.GetType(), typeof(CompilerGeneratedAttribute));
Console.WriteLine(isClosure);

当然,您可以通过手动将[CompilerGenerated]添加到您选择的任何类型来强制误报。

您也可以使用action.Method.DeclaringType ,但是由于所有捕获都涉及目标实例,因此保留Target检查很有用:

bool isClosure = action.Target != null && Attribute.IsDefined(
    action.Method.DeclaringType, typeof(CompilerGeneratedAttribute));

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM