diff --git a/src/CsvHelper/ObjectCreator.cs b/src/CsvHelper/ObjectCreator.cs index 738801999..31851e00a 100644 --- a/src/CsvHelper/ObjectCreator.cs +++ b/src/CsvHelper/ObjectCreator.cs @@ -13,7 +13,7 @@ namespace CsvHelper; /// public class ObjectCreator { - private readonly Dictionary> cache = new Dictionary>(); + private readonly Dictionary> cache = new Dictionary>(); /// /// Creates an instance of type T using the given arguments. @@ -41,7 +41,7 @@ public object CreateInstance(Type type, params object?[] args) private Func GetFunc(Type type, object?[] args) { var argTypes = GetArgTypes(args); - var key = GetConstructorCacheKey(type, argTypes); + var key = new CacheKey(type, argTypes); if (!cache.TryGetValue(key, out var func)) { cache[key] = func = CreateInstanceFunc(type, argTypes); @@ -62,19 +62,6 @@ private static Type[] GetArgTypes(object?[] args) return argTypes; } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static int GetConstructorCacheKey(Type type, Type[] args) - { - var hashCode = new HashCode(); - hashCode.Add(type.GetHashCode()); - for (var i = 0; i < args.Length; i++) - { - hashCode.Add(args[i].GetHashCode()); - } - - return hashCode.ToHashCode(); - } - [MethodImpl(MethodImplOptions.AggressiveInlining)] private static Func CreateInstanceFunc(Type type, Type[] argTypes) { @@ -195,4 +182,51 @@ private enum MatchType Exact = 1, Fuzzy = 2 } + + internal struct CacheKey : IEquatable + { + private readonly Type _type; + private readonly Type[] _args; + + public CacheKey(Type type, Type[] args) + { + _type = type; + _args = args; + } + + public override int GetHashCode() + { + var hashCode = new HashCode(); + hashCode.Add(_type.GetHashCode()); + for (var i = 0; i < _args.Length; i++) + { + hashCode.Add(_args[i].GetHashCode()); + } + + return hashCode.ToHashCode(); + } + + public override bool Equals(object? obj) + { + if (obj == null) return false; + + if (obj is CacheKey key) + { + return Equals(key); + } + + return false; + } + + public bool Equals(CacheKey other) + { + if (other._type != _type) return false; + if (other._args.Length != _args.Length) return false; + for (var i = 0; i < _args.Length; i++) + { + if (other._args[i] != _args[i]) return false; + } + return true; + } + } }