gpt4 book ai didi

c# - IDE/编译器如何知道一个 lambda 表达式被立即执行而不是被保存以备后用?

转载 作者:太空宇宙 更新时间:2023-11-03 18:54:51 25 4
gpt4 key购买 nike

编译器(我在这里随意使用这个词,我的 VS、Roslyn、R# 工具链中的某个人)知道我何时访问 lambda 表达式中的变量,如果稍后执行,可能已经被释放。这是一个很棒的功能和一个受欢迎的警告。但是,有时我知道 lambda 表达式将立即 执行并且不会保存供以后使用,所以这个警告是错误的。

有人可能会争辩说,编译器无法知道 lambda 表达式是被执行还是保留以备后用。有趣的事实:确实如此。如果我在 LinQ 语句中使用它,我会得到波浪形的警告行,except 因为当我通过调用 .ToList() 立即具体化事物时。然后警告消失。因此,编译器知道 lambda 是使用一次就丢弃,还是保留以备后用。

使用波浪线访问已处置的闭包:

enter image description here

我如何向我的工具链解释我的方法(采用 lambda 的 .ThrownFrom()) 实际上是立即执行它并且不引用它?

我能否通过属性、模式或其他我可以设置的东西获得与具体化 LinQ 相同的效果,或者是 LinQ 特有的一些硬编码编译器魔法?


以我的忽略类为例:

public static class Ignore<TException> where TException : Exception
{
public static void ThrownFrom([NotNull] Action action)
{
if (action is null)
{
throw new ArgumentNullException(nameof(action));
}

try
{
action();
}
catch (TException ex)
{
// ignore
}
}
}

最佳答案

One might argue that the compiler cannot know whether the lambda expression is executed or kept for later use.

这样的论点是正确的。它假定可以在应用程序 future 的任意时间点调用任何 lambda,并相应地编译代码。

Fun fact: it does. If I use this in a LinQ statement, I get the squiggly warning line, except for when I materialize the thing immediately with for example a call to .ToList(). Then the warning vanishes. So the compiler knows if a lambda is used once and discarded, or kept for later use.

不,编译器不会做这样的事情。一些代码分析工具试图确定给定的 lambda 是否可以在给定范围之外调用,但他们无法知道。在一般情况下不可能知道,但在某些特定情况下您有时可以知道。他们只是硬编码了一堆特定情况,在这些情况下他们知道或不知道是否立即调用 lambda(在这种情况下,他们只是将某些框架硬编码到代码分析工具中方法会立即调用提供的委托(delegate),其他人会保留它以备后用)。鉴于此,他们有时会犯错误,因为有很多方法他们根本不知道委托(delegate)是否被持有。

How can I explain to my toolchain that my method (the .ThrownFrom() that takes a lambda) is in fact executing it immediately and keeps no reference to it?

您可以查看您使用的任何代码分析工具的文档。他们可能会提供这样做的方法,也可能不会。

关于c# - IDE/编译器如何知道一个 lambda 表达式被立即执行而不是被保存以备后用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48212003/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com