【问题标题】:C# LINQ behavior [duplicate]C# LINQ 行为 [重复]
【发布时间】:2018-09-26 07:29:52
【问题描述】:

我遇到了一个案例,我在下面的代码中执行,结果让我大开眼界。

当我在 ILSPY 工具中反编译上述代码时,在相等检查之前创建了一个新的 displayType 对象。为什么有必要?这样做有什么作用?

public override bool CheckSupport(DisplayType displayType)
{
     return Displays.Any(x => x.DisplayType == displayType);
}

【问题讨论】:

  • 包含您正在讨论的 IL 代码可能很有用。
  • x => ... 是一种匿名方法。编译器会为您创建一个包含该方法的类。
  • 什么是DisplayType?类还是结构?
  • 您还应该包括结果以及当结果是“让您大开眼界”时您的预期。
  • 请不要发布源代码的图像,因为很难在调试器中尝试以重现您的问题。而是发布实际代码。

标签: c# linq


【解决方案1】:

这不是DisplayTypeDisplay 的新实例。它是表示 lambda 表达式的对象。

当我在SharpLab.io 中尝试此代码时:

public class DisplayType
{
}

public class Display
{
    public DisplayType DisplayType {get;set;}
}

public class C {
    public Display[] Displays=new Display[0];

    public bool CheckSupport(DisplayType displayType)
    {
         return Displays.Any(x => x.DisplayType == displayType);
    }
}

编译器生成的 C 类代码如下所示:

public class C
{
    [CompilerGenerated]
    private sealed class <>c__DisplayClass1_0
    {
        public DisplayType displayType;

        internal bool <CheckSupport>b__0(Display x)
        {
            return x.DisplayType == displayType;
        }
    }

    public Display[] Displays = new Display[0];

    public bool CheckSupport(DisplayType displayType)
    {
        <>c__DisplayClass1_0 <>c__DisplayClass1_ = new <>c__DisplayClass1_0();
        <>c__DisplayClass1_.displayType = displayType;
        return Displays.Any(<>c__DisplayClass1_.<CheckSupport>b__0);
    }
}

&lt;&gt;c__DisplayClass1_ 是编译器生成的类,其&lt;CheckSupport&gt;b__0 方法实现了传递给Any 的谓词。

    private sealed class <>c__DisplayClass1_0
    {
        public DisplayType displayType;

        internal bool <CheckSupport>b__0(Display x)
        {
            return x.DisplayType == displayType;
        }
    }

声明:

<>c__DisplayClass1_.displayType = displayType;

捕获 displayType 的值以供 lambda 使用。

【讨论】:

  • 你从来没有解释过为什么
  • @SelmanGenç 我在第一行做了。这就是编译器为 lambda 生成的内容。 It's not a new instance of DisplayType or Display. It's the object that represents the lambda expression.
  • OP 从未声称它是显示类型的实例。再次阅读问题
  • @SelmanGenç“为 displayType 创建了一个新对象”对我来说听起来很像。
  • “for displayType”不是“displayType 的实例”
【解决方案2】:

这是因为你的 lambda 从函数中“捕获”了一个变量(函数参数)。因为该 lambda 可能会在函数返回后被调用(它不会在这里,但编译器不知道),它创建了一个辅助类来保存对它的引用,以便 lambda 代码可以安全地引用它。

【讨论】:

  • 为什么它被否决了?
  • 可能是因为您在这里发布了屏幕截图而不是粘贴代码
猜你喜欢
  • 2019-02-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-26
相关资源
最近更新 更多