【问题标题】:Fixing Resharper's "Implicitly captured closure: this" [duplicate]修复 Resharper 的“隐式捕获的闭包:this”[重复]
【发布时间】:2018-01-05 19:46:16
【问题描述】:

据我了解,在 resharper 建议“隐式捕获的闭包:this”中,this 指的是HomeController 类的实例。现在的问题是为什么以下解决方案能够解决问题并删除 Resharper 建议。

public class HomeController : Controller
{
    private ExcelDocument _excelDoc = new ExcelDocument();
    private IDatabase _database = new CoreDatabase();

    [HttpPost]
    public JsonResult Insert(HttpPostedFileBase file, int programId)
    {
        _excelDoc.ReadData(firstDataRowIdx: 1, headerRowIdx: 0, excelFile: file);

        _excelDoc.CompareToDatabaseCodes(_database.
             .GetCodesWhere(c => c.ProgramID == programId && c.Active)// In this lambda Resharper says: 'Implicitly captured closure: this'
             .Select(rc => rc.Code)
             .ToList());

        _excelDoc.InsertTireIds(_database
             .GetTiersWhere(t => t.ProgramID == programId && _excelDoc.DistinctTiers.Contains(t.Tier)));

        //More code...
    }
}

我发现了两种删除 Resharper 建议的方法,但并没有真正理解这些修复背后的原因。

  1. 将 programId 参数分配给局部变量,如下所示:

    [HttpPost]
    public JsonResult Insert(HttpPostedFileBase file, int programId)
    {
        _excelDoc.ReadData(firstDataRowIdx: 1, headerRowIdx: 0, excelFile: file);
    
        // Fix 
        int selectedProgramId = programId;
    
        _excelDoc.CompareToDatabaseCodes(_database.
             .GetCodesWhere(c => c.ProgramID == selectedProgramId && c.Active)// In this lambda Resharper says: 'Implicitly captured closure: this'
             .Select(rc => rc.Code)
             .ToList());
    
        _excelDoc.InsertTireIds(_database
             .GetTiersWhere(t => t.ProgramID == selectedProgramId && _excelDoc.DistinctTiers.Contains(t.Tier)));
        //More code...
    }
    
  2. 将 _excelDoc.DistinctTiers(在第二个 lambda 中)分配给局部变量:

    [HttpPost]
    public JsonResult Insert(HttpPostedFileBase file, int programId)
    {
        _excelDoc.ReadData(firstDataRowIdx: 1, headerRowIdx: 0, excelFile: file); 
    
        _excelDoc.CompareToDatabaseCodes(_database.
             .GetCodesWhere(c => c.ProgramID == programId && c.Active)// In this lambda Resharper says: 'Implicitly captured closure: this'
             .Select(rc => rc.Code)
             .ToList());
    
        // Fix 
        List<int> distinctTiers = _excelDoc.DistinctTiers;
    
        _excelDoc.InsertTireIds(_database
             .GetTiersWhere(t => t.ProgramID == programId && distinctTiers.Contains(t.Tier)));
    
        //More code...
    }
    

请帮助我了解为什么我的修复有效。

如果需要更多信息来更好地解释问题,请告诉我。

谢谢!!!

【问题讨论】:

  • this 指的是您的类实例。因为 lambda 正在访问_excelDoc instance 字段,所以它需要捕获当前实例。
  • 我现在明白this 指的是什么。但是,我仍然无法理解为什么我删除该建议的两种解决方案都有效。 _excelDoc 还在:/
  • @НикитаУрюпин 副本准确地解释了错误消息试图警告您的内容,以及您使用的确切修复程序解决该问题的原因。
  • @Servy 我仍然不明白将方法参数/类字段分配给局部变量是如何解决的。另外,两种完全不同的方法怎么可能解决同一个问题。我已经多次阅读重复的线程。
  • @НикитаУрюпин 分配本地会更改关闭的内容,并且由于警告基于您要关闭的内容,因此会影响它。

标签: c# lambda this resharper


【解决方案1】:

这意味着你在 lamda 表达式中包含了类中的一个字段。因为 Resharper 不知道该 lamda 将用于什么,所以无法确定它是否会超出方法调用的范围。例如,如果将该 lamda 分配给另一个类的某个长期存在的字段,它将引用 this._excelDoc 的当前值 - 同时可能已更改,或设置为 null 等...

Resharper 只是告诉你 lamda 的生命周期不应超出方法的范围,否则它将继续在此实例引用的 _excelDoc 上运行。

【讨论】:

  • 这是 HomeController 类实例 - 可以制作场景。仍然不明白这两种解决方案如何为我解决了这个问题。
猜你喜欢
  • 2012-10-08
  • 2013-09-22
  • 2013-06-10
  • 2012-11-17
  • 2016-08-05
  • 1970-01-01
  • 1970-01-01
  • 2013-04-23
  • 2022-11-19
相关资源
最近更新 更多