Skip to content

Commit 71b7039

Browse files
committed
Use ref struct as disposable instance to avoid heap allocation in LinqBindingCollection.LinkParameters method
1 parent 44623f6 commit 71b7039

File tree

1 file changed

+30
-11
lines changed

1 file changed

+30
-11
lines changed

Orm/Xtensive.Orm/Orm/Linq/LinqBindingCollection.cs

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
using System.Collections.Generic;
99
using System.Linq.Expressions;
1010
using Xtensive.Collections;
11-
using Xtensive.Core;
1211
using Xtensive.Orm.Linq.Expressions;
1312

1413
namespace Xtensive.Orm.Linq
@@ -31,16 +30,18 @@ public override BindingScope Add(ParameterExpression key, ProjectionExpression v
3130

3231
public override void PermanentAdd(ParameterExpression key, ProjectionExpression value)
3332
{
34-
if (!key.Type.IsAssignableFrom(value.ItemProjector.Type))
35-
throw new ArgumentException(Strings.ExParameterExpressionMustHaveSameTypeAsProjectionExpressionItemProjector, "key");
33+
if (!key.Type.IsAssignableFrom(value.ItemProjector.Type)) {
34+
throw new ArgumentException(
35+
Strings.ExParameterExpressionMustHaveSameTypeAsProjectionExpressionItemProjector, nameof(key));
36+
}
37+
3638
base.PermanentAdd(key, value);
3739
}
3840

3941
public override void ReplaceBound(ParameterExpression key, ProjectionExpression value)
4042
{
4143
base.ReplaceBound(key, value);
42-
IEnumerable<ParameterExpression> parameters;
43-
if (linkedParameters.TryGetValue(key, out parameters)) {
44+
if (linkedParameters.TryGetValue(key, out var parameters)) {
4445
foreach (var parameter in parameters) {
4546
if (parameter!=key) {
4647
var projection = this[parameter];
@@ -55,16 +56,34 @@ public override void ReplaceBound(ParameterExpression key, ProjectionExpression
5556
}
5657
}
5758
}
58-
59-
public Disposable LinkParameters(IEnumerable<ParameterExpression> parameters)
59+
60+
internal readonly ref struct ParameterScope
6061
{
61-
foreach (var parameter in parameters)
62-
linkedParameters.Add(parameter, parameters);
63-
return new Disposable(isDisposing => {
62+
private readonly LinqBindingCollection owner;
63+
private readonly IReadOnlyCollection<ParameterExpression> parameters;
64+
65+
public void Dispose()
66+
{
67+
var linkedParameters = owner.linkedParameters;
6468
foreach (var parameter in parameters) {
6569
linkedParameters.Remove(parameter);
6670
}
67-
});
71+
}
72+
73+
public ParameterScope(LinqBindingCollection owner, IReadOnlyCollection<ParameterExpression> parameters)
74+
{
75+
this.owner = owner;
76+
this.parameters = parameters;
77+
}
78+
}
79+
80+
public ParameterScope LinkParameters(IReadOnlyCollection<ParameterExpression> parameters)
81+
{
82+
foreach (var parameter in parameters) {
83+
linkedParameters.Add(parameter, parameters);
84+
}
85+
86+
return new ParameterScope(this, parameters);
6887
}
6988
}
7089
}

0 commit comments

Comments
 (0)