// Copyright (c) All contributors. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System; using System.Linq.Expressions; namespace MessagePack.Formatters { /// /// Provides general helpers for creating collections (including dictionaries). /// /// The concrete type of collection to create. /// The type of equality comparer that we would hope to pass into the collection's constructor. internal static class CollectionHelpers where TCollection : new() { /// /// The delegate that will create the collection, if the typical (int count, IEqualityComparer{T} equalityComparer) constructor was found. /// private static Func collectionCreator; /// /// Initializes static members of the class. /// /// /// Initializes a delegate that is optimized to create a collection of a given size and using the given equality comparer, if possible. /// static CollectionHelpers() { var ctor = typeof(TCollection).GetConstructor(new Type[] { typeof(int), typeof(TEqualityComparer) }); if (ctor != null) { ParameterExpression param1 = Expression.Parameter(typeof(int), "count"); ParameterExpression param2 = Expression.Parameter(typeof(TEqualityComparer), "equalityComparer"); NewExpression body = Expression.New(ctor, param1, param2); collectionCreator = Expression.Lambda>(body, param1, param2).Compile(); } } /// /// Initializes a new instance of the collection. /// /// The number of elements the collection should be prepared to receive. /// The equality comparer to initialize the collection with. /// The newly initialized collection. /// /// Use of the and are a best effort. /// If we can't find a constructor on the collection in the expected shape, we'll just instantiate the collection with its default constructor. /// internal static TCollection CreateHashCollection(int count, TEqualityComparer equalityComparer) => collectionCreator != null ? collectionCreator.Invoke(count, equalityComparer) : new TCollection(); } }