关闭分配的含义和问题

我正在使用JetBrains Rider进行C#编程,并且我猜想在使用ReSharper时也会出现此警告:


我写了这个函数GetTicket:


public async Task<IEnumerable<Ticket>> GetTicket(int id)

{

    return await _memoryCache.GetOrCreateAsync(_cachingFunctionalty.BuildCachingName(id), entry =>

    {

        entry.SlidingExpiration = TimeSpan.FromSeconds(10);

        return GetTicket_uncached(id);

    });

}

和GetTicket_uncached,它称为:


private async Task<IEnumerable<Ticket>> GetTicket_uncached(int id)

{

    RestClient client = new RestClient(ServiceAdress);

    Request req = new Request

    {

        Method = Method.GET,

        Resource = "api/tickets/get",

        Parameters = new {ident = id}

    };


    return await client.ExecuteRequestAsync<Ticket[]>(req);

}

因此,id方法中的参数public async Task<IEnumerable<Ticket>> GetTicket(int id)会以以下警告突出显示:


关闭分配:“ id”参数和“ this”参考


在谷歌搜索时发现了一些东西,但我仍然不知道这意味着什么,这是什么问题?


慕勒3428872
浏览 176回答 2
2回答

慕村9548890

期望您进行如下设计:public async Task<IEnumerable<Ticket>> GetTicket(int id){&nbsp; &nbsp; return await _memoryCache.GetOrCreateAsync(_cachingFunctionalty.BuildCachingName(id), entry =>&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; var localId = id;&nbsp; &nbsp; &nbsp; &nbsp; entry.SlidingExpiration = TimeSpan.FromSeconds(10);&nbsp; &nbsp; &nbsp; &nbsp; return GetTicket_uncached(localId);&nbsp; &nbsp; });}现在您没有可以在闭包范围之外修改的变量,Re-sharper会发出警告,只要理论上有可能在正在执行的闭包之外修改变量,从而导致不可预测的结果。同样适用于其他方法。在实际操作中,您应该对所有其他对象遵循相同的操作,可以在闭包范围之外对其进行修改,从而创建本地版本

慕的地8271018

此消息来自“堆分配查看器”插件。创建lambda并传递Func给时GetOrCreateAsync,您要从调用方法(GetTicket)中捕获一些值,并在以后使用它们。编译此代码时,编译器会将此lambda重写为一个保存值的类,以及一个主体与lambda主体相同的方法,尽管它将使用在此新类中捕获的值,而不是原始的方法调用。堆分配查看器插件的意思是,在运行时这里发生了隐藏分配-正在分配此新的编译器生成的类,分配了值并调用了方法。插件告诉您id正在捕获和分配此新类-在lambda中这很明显,因为您在代码中看到了它。但是您也正在捕获this,因为它GetTicket_uncached是一个实例方法而不是静态方法。没有this,您将无法调用实例方法,因此id和this都将在编译器生成的类中被捕获和分配。您无法摆脱id变量的分配,但是this如果您将其GetTicket_uncached设为静态,则可以摆脱引用(但这可能需要传入ServiceAddress,在这种情况下,堆分配查看器会告诉您您正在关闭分配现在id和ServiceAddress)。您可以在ReSharper帮助页面中看到有关“隐式捕获关闭”警告的更多详细信息。在讨论不同的场景和警告消息时,有关分配类以捕获变量的背景详细信息很有用。
打开App,查看更多内容
随时随地看视频慕课网APP