ZK_Framework/Assets/Plugins/MessagePack/Formatters/CollectionHelpers`2.cs

53 lines
2.9 KiB
C#

// 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
{
/// <summary>
/// Provides general helpers for creating collections (including dictionaries).
/// </summary>
/// <typeparam name="TCollection">The concrete type of collection to create.</typeparam>
/// <typeparam name="TEqualityComparer">The type of equality comparer that we would hope to pass into the collection's constructor.</typeparam>
internal static class CollectionHelpers<TCollection, TEqualityComparer>
where TCollection : new()
{
/// <summary>
/// The delegate that will create the collection, if the typical (int count, IEqualityComparer{T} equalityComparer) constructor was found.
/// </summary>
private static Func<int, TEqualityComparer, TCollection> collectionCreator;
/// <summary>
/// Initializes static members of the <see cref="CollectionHelpers{TCollection, TEqualityComparer}"/> class.
/// </summary>
/// <remarks>
/// Initializes a delegate that is optimized to create a collection of a given size and using the given equality comparer, if possible.
/// </remarks>
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<Func<int, TEqualityComparer, TCollection>>(body, param1, param2).Compile();
}
}
/// <summary>
/// Initializes a new instance of the <typeparamref name="TCollection"/> collection.
/// </summary>
/// <param name="count">The number of elements the collection should be prepared to receive.</param>
/// <param name="equalityComparer">The equality comparer to initialize the collection with.</param>
/// <returns>The newly initialized collection.</returns>
/// <remarks>
/// Use of the <paramref name="count"/> and <paramref name="equalityComparer"/> 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.
/// </remarks>
internal static TCollection CreateHashCollection(int count, TEqualityComparer equalityComparer) => collectionCreator != null ? collectionCreator.Invoke(count, equalityComparer) : new TCollection();
}
}