Resharper 关于关闭的警告是否正确?
Are Resharper's warnings about closures correct?
今天我遇到了以下情况
public async Task<Stream> GetApproveDocumentAsync<T>(Guid id, int revision, PdfLayoutType pdfLayoutType, string resourceFilePath, CadDrawingType cadDrawingType, int approvalWidth, int approvalHeight, Action<T> fillModelAction = null) where T : BaseApproveModel, new() {
var previewFileName = $"{id}_{revision}_preview.png";
Stream previewFile;
using (var resourceFileStream = new FileStream(resourceFilePath, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, true)) {
previewFile = await _cadApiService.ConvertDrawingToImageAsync(resourceFileStream, cadDrawingType, FileFormat.EVD, FileFormat.PNG, approvalWidth, approvalHeight).ConfigureAwait(false);
}
Func<string[], T> createBaseApproveModelFunc = graphicContentFilenames => { //Implicitly captured closure: previewFile
var model = new T {
GraphicContentFiles = graphicContentFilenames,
CadPreview = previewFileName,
Customer = _userService.GetCurrentOverrideCustomer()?.CustomerName
};
fillModelAction?.Invoke(model);
return model;
};
Action<List<StreamWithFileName>> fillGraphicContentAction = currentGraphicContent => { //Implicitly captured closure: fillModelAction, this
currentGraphicContent.Add(new StreamWithFileName {FileName = previewFileName, Stream = previewFile});
};
return await _apagoService.ConstcutPdf(pdfLayoutType, createBaseApproveModelFunc, fillGraphicContentAction).ConfigureAwait(false);
}
我以为我知道闭包是如何工作的,但我无法理解 ReSharper 的行为。 ReSharper 是否错误(或错误)交换了这两个警告?
我正在使用 ReSharper Ultimate 2016.2.2
我 认为 resharper 告诉您的是,这两个闭包 也 捕获了您的代码 不认为它在那个 lambda 中使用 。第一个闭包使用 previewFileName
和 this
(对于字段 _userService
),因此您对这些的捕获显然是有意的 - 但是:您可能并不明显地也在捕获previewFile
。你捕获额外东西的原因是因为捕获的项目的 scope 是相同的,所以编译器生成一个闭包来捕获所有 previewFile
, this
、previewFileName
和 fillModelAction
- 并且闭包实例有 两个 方法 - 一个用于 Func<string[], T>
,一个用于 Action<List<StreamWithFileName>>
。请注意,previewFileName
被两个 lambda 表达式使用,因此:没有警告。
出于垃圾收集的原因,了解这一点可能很重要 - 如果一个 lambda 比另一个活得长得多,您可能不想意外地让其他东西保持活动状态,因此会出现警告。例如,fillGraphicContentAction
lambda 使整个 this
保持活动状态(无论 this
是什么),即使 lambda 不使用 this
.
今天我遇到了以下情况
public async Task<Stream> GetApproveDocumentAsync<T>(Guid id, int revision, PdfLayoutType pdfLayoutType, string resourceFilePath, CadDrawingType cadDrawingType, int approvalWidth, int approvalHeight, Action<T> fillModelAction = null) where T : BaseApproveModel, new() {
var previewFileName = $"{id}_{revision}_preview.png";
Stream previewFile;
using (var resourceFileStream = new FileStream(resourceFilePath, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, true)) {
previewFile = await _cadApiService.ConvertDrawingToImageAsync(resourceFileStream, cadDrawingType, FileFormat.EVD, FileFormat.PNG, approvalWidth, approvalHeight).ConfigureAwait(false);
}
Func<string[], T> createBaseApproveModelFunc = graphicContentFilenames => { //Implicitly captured closure: previewFile
var model = new T {
GraphicContentFiles = graphicContentFilenames,
CadPreview = previewFileName,
Customer = _userService.GetCurrentOverrideCustomer()?.CustomerName
};
fillModelAction?.Invoke(model);
return model;
};
Action<List<StreamWithFileName>> fillGraphicContentAction = currentGraphicContent => { //Implicitly captured closure: fillModelAction, this
currentGraphicContent.Add(new StreamWithFileName {FileName = previewFileName, Stream = previewFile});
};
return await _apagoService.ConstcutPdf(pdfLayoutType, createBaseApproveModelFunc, fillGraphicContentAction).ConfigureAwait(false);
}
我以为我知道闭包是如何工作的,但我无法理解 ReSharper 的行为。 ReSharper 是否错误(或错误)交换了这两个警告?
我正在使用 ReSharper Ultimate 2016.2.2
我 认为 resharper 告诉您的是,这两个闭包 也 捕获了您的代码 不认为它在那个 lambda 中使用 。第一个闭包使用 previewFileName
和 this
(对于字段 _userService
),因此您对这些的捕获显然是有意的 - 但是:您可能并不明显地也在捕获previewFile
。你捕获额外东西的原因是因为捕获的项目的 scope 是相同的,所以编译器生成一个闭包来捕获所有 previewFile
, this
、previewFileName
和 fillModelAction
- 并且闭包实例有 两个 方法 - 一个用于 Func<string[], T>
,一个用于 Action<List<StreamWithFileName>>
。请注意,previewFileName
被两个 lambda 表达式使用,因此:没有警告。
出于垃圾收集的原因,了解这一点可能很重要 - 如果一个 lambda 比另一个活得长得多,您可能不想意外地让其他东西保持活动状态,因此会出现警告。例如,fillGraphicContentAction
lambda 使整个 this
保持活动状态(无论 this
是什么),即使 lambda 不使用 this
.