次のコードがあります:
public double CalculateDailyProjectPullForceMax(DateTime date, string start = null, string end = null)
{
Log("Calculating Daily Pull Force Max...");
var pullForceList = start == null
? _pullForce.Where((t, i) => _date[i] == date).ToList() // implicitly captured closure: end, start
: _pullForce.Where(
(t, i) => _date[i] == date && DateTime.Compare(_time[i], DateTime.Parse(start)) > 0 &&
DateTime.Compare(_time[i], DateTime.Parse(end)) < 0).ToList();
_pullForceDailyMax = Math.Round(pullForceList.Max(), 2, MidpointRounding.AwayFromZero);
return _pullForceDailyMax;
}
さて、私はその行にコメントを追加しましたリシャーパー変更を提案しています。これはどういう意味ですか、またはなぜ変更する必要があるのですか?implicitly captured closure: end, start
ベストアンサー1
警告は、このメソッド内のラムダが存続するため、変数end
も存続することを通知します。start
短い例を見てみましょう
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
int i = 0;
Random g = new Random();
this.button1.Click += (sender, args) => this.label1.Text = i++.ToString();
this.button2.Click += (sender, args) => this.label1.Text = (g.Next() + i).ToString();
}
最初のラムダで「暗黙的にキャプチャされたクロージャ:g」という警告が出ますg
。ゴミ収集最初のラムダが使用されている限り。
コンパイラは両方のラムダ式のクラスを生成し、ラムダ式で使用されるすべての変数をそのクラスに配置します。
したがって、私の例ではg
、 と はi
デリゲートの実行のために同じクラスに保持されます。g
が大量のリソースが残っている重いオブジェクトである場合、ラムダ式が使用されている限りこのクラス内の参照がまだ有効なため、ガベージ コレクターはそれを回収できません。したがって、これは潜在的なメモリ リークであり、これが R# 警告の原因です。
@splintor C# と同様に、匿名メソッドは常にメソッドごとに 1 つのクラスに格納されますが、これを回避するには 2 つの方法があります。
匿名メソッドの代わりにインスタンスメソッドを使用します。
ラムダ式の作成を 2 つの方法に分割します。