Skip to content

Commit 08060f6

Browse files
committed
Merge branch 'scottfavre-scottfavre/thread-safe-object-resolver'
2 parents 5d36c11 + f54ec00 commit 08060f6

File tree

1 file changed

+61
-15
lines changed

1 file changed

+61
-15
lines changed

src/CsvHelper/ObjectCreator.cs

Lines changed: 61 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ namespace CsvHelper;
1313
/// </summary>
1414
public class ObjectCreator
1515
{
16-
private readonly Dictionary<int, Func<object?[], object>> cache = new Dictionary<int, Func<object?[], object>>();
16+
private readonly Dictionary<CacheKey, Func<object?[], object>> cache = new Dictionary<CacheKey, Func<object?[], object>>();
1717

1818
/// <summary>
1919
/// Creates an instance of type T using the given arguments.
@@ -41,7 +41,7 @@ public object CreateInstance(Type type, params object?[] args)
4141
private Func<object?[], object> GetFunc(Type type, object?[] args)
4242
{
4343
var argTypes = GetArgTypes(args);
44-
var key = GetConstructorCacheKey(type, argTypes);
44+
var key = new CacheKey(type, argTypes);
4545
if (!cache.TryGetValue(key, out var func))
4646
{
4747
cache[key] = func = CreateInstanceFunc(type, argTypes);
@@ -62,19 +62,6 @@ private static Type[] GetArgTypes(object?[] args)
6262
return argTypes;
6363
}
6464

65-
[MethodImpl(MethodImplOptions.AggressiveInlining)]
66-
private static int GetConstructorCacheKey(Type type, Type[] args)
67-
{
68-
var hashCode = new HashCode();
69-
hashCode.Add(type.GetHashCode());
70-
for (var i = 0; i < args.Length; i++)
71-
{
72-
hashCode.Add(args[i].GetHashCode());
73-
}
74-
75-
return hashCode.ToHashCode();
76-
}
77-
7865
[MethodImpl(MethodImplOptions.AggressiveInlining)]
7966
private static Func<object?[], object> CreateInstanceFunc(Type type, Type[] argTypes)
8067
{
@@ -195,4 +182,63 @@ private enum MatchType
195182
Exact = 1,
196183
Fuzzy = 2
197184
}
185+
186+
private struct CacheKey : IEquatable<CacheKey>
187+
{
188+
private readonly Type type;
189+
private readonly Type[] args;
190+
191+
public CacheKey(Type type, Type[] args)
192+
{
193+
this.type = type;
194+
this.args = args;
195+
}
196+
197+
public override int GetHashCode()
198+
{
199+
var hashCode = new HashCode();
200+
hashCode.Add(type.GetHashCode());
201+
for (var i = 0; i < args.Length; i++)
202+
{
203+
hashCode.Add(args[i].GetHashCode());
204+
}
205+
206+
return hashCode.ToHashCode();
207+
}
208+
209+
public override bool Equals(object? obj)
210+
{
211+
if (obj == null)
212+
{
213+
return false;
214+
}
215+
216+
if (obj is CacheKey key)
217+
{
218+
return Equals(key);
219+
}
220+
221+
return false;
222+
}
223+
224+
public bool Equals(CacheKey other)
225+
{
226+
if (other.type != type)
227+
{
228+
return false;
229+
}
230+
231+
if (other.args.Length != args.Length)
232+
{
233+
return false;
234+
}
235+
236+
for (var i = 0; i < args.Length; i++)
237+
{
238+
if (other.args[i] != args[i]) return false;
239+
}
240+
241+
return true;
242+
}
243+
}
198244
}

0 commit comments

Comments
 (0)