Merge pull request #1151 from JonHanna/singleton_empty_array
Use singleton for zero-element arrays.
This commit is contained in:
@@ -538,7 +538,7 @@ namespace Newtonsoft.Json
|
||||
Guid g;
|
||||
if (s.Length == 0)
|
||||
{
|
||||
data = new byte[0];
|
||||
data = CollectionUtils.ArrayEmpty<byte>();
|
||||
}
|
||||
else if (ConvertUtils.TryConvertGuid(s, out g))
|
||||
{
|
||||
|
||||
@@ -146,7 +146,7 @@ namespace Newtonsoft.Json
|
||||
byte[] data;
|
||||
if (_stringReference.Length == 0)
|
||||
{
|
||||
data = new byte[0];
|
||||
data = CollectionUtils.ArrayEmpty<byte>();
|
||||
}
|
||||
else if (_stringReference.Length == 36 && ConvertUtils.TryConvertGuid(_stringReference.ToString(), out g))
|
||||
{
|
||||
|
||||
@@ -88,7 +88,7 @@ namespace Newtonsoft.Json.Linq.JsonPath
|
||||
return JPath.Evaluate(pathFilters, root, t, false);
|
||||
}
|
||||
|
||||
return new JToken[0];
|
||||
return CollectionUtils.ArrayEmpty<JToken>();
|
||||
}
|
||||
|
||||
public override bool IsMatch(JToken root, JToken t)
|
||||
|
||||
@@ -2274,7 +2274,7 @@ namespace Newtonsoft.Json.Serialization
|
||||
return CreateObjectUsingCreatorWithParameters(reader, objectContract, containerMember, objectContract.OverrideCreator, id);
|
||||
}
|
||||
|
||||
newObject = objectContract.OverrideCreator(new object[0]);
|
||||
newObject = objectContract.OverrideCreator(CollectionUtils.ArrayEmpty<object>());
|
||||
}
|
||||
else if (objectContract.DefaultCreator != null &&
|
||||
(!objectContract.DefaultCreatorNonPublic || Serializer._constructorHandling == ConstructorHandling.AllowNonPublicDefaultConstructor || objectContract.ParameterizedCreator == null))
|
||||
|
||||
@@ -745,7 +745,7 @@ namespace Newtonsoft.Json.Serialization
|
||||
|
||||
bool hasWrittenMetadataObject = WriteStartArray(writer, values, contract, member, collectionContract, containerProperty);
|
||||
|
||||
SerializeMultidimensionalArray(writer, values, contract, member, writer.Top, new int[0]);
|
||||
SerializeMultidimensionalArray(writer, values, contract, member, writer.Top, CollectionUtils.ArrayEmpty<int>());
|
||||
|
||||
if (hasWrittenMetadataObject)
|
||||
{
|
||||
|
||||
@@ -29,12 +29,16 @@ using System.Collections.ObjectModel;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Collections;
|
||||
using System.Diagnostics;
|
||||
#if NET20
|
||||
using Newtonsoft.Json.Utilities.LinqBridge;
|
||||
#else
|
||||
using System.Linq;
|
||||
#endif
|
||||
using System.Globalization;
|
||||
#if !(NET20 || NET35 || NET40 || PORTABLE40)
|
||||
using System.Runtime.CompilerServices;
|
||||
#endif
|
||||
using Newtonsoft.Json.Serialization;
|
||||
|
||||
namespace Newtonsoft.Json.Utilities
|
||||
@@ -340,9 +344,30 @@ namespace Newtonsoft.Json.Utilities
|
||||
}
|
||||
|
||||
Array multidimensionalArray = Array.CreateInstance(type, dimensions.ToArray());
|
||||
CopyFromJaggedToMultidimensionalArray(values, multidimensionalArray, new int[0]);
|
||||
CopyFromJaggedToMultidimensionalArray(values, multidimensionalArray, ArrayEmpty<int>());
|
||||
|
||||
return multidimensionalArray;
|
||||
}
|
||||
|
||||
// 4.6 has Array.Empty<T> to return a cached empty array. Lacking that in other
|
||||
// frameworks, Enumerable.Empty<T> happens to be implemented as a cached empty
|
||||
// array in all versions (in .NET Core the same instance as Array.Empty<T>).
|
||||
// This includes the internal Linq bridge for 2.0.
|
||||
// Since this method is simple and only 11 bytes long in a release build it's
|
||||
// pretty much guaranteed to be inlined, giving us fast access of that cached
|
||||
// array. With 4.5 and up we use AggressiveInlining just to be sure, so it's
|
||||
// effectively the same as calling Array.Empty<T> even when not available.
|
||||
#if !(NET20 || NET35 || NET40 || PORTABLE40)
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
public static T[] ArrayEmpty<T>()
|
||||
{
|
||||
T[] array = Enumerable.Empty<T>() as T[];
|
||||
Debug.Assert(array != null);
|
||||
// Defensively guard against a version of Linq where Enumerable.Empty<T> doesn't
|
||||
// return an array, but throw in debug versions so a better strategy can be
|
||||
// used if that ever happens.
|
||||
return array ?? new T[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -37,7 +37,7 @@ namespace Newtonsoft.Json.Utilities
|
||||
{
|
||||
public virtual IEnumerable<string> GetDynamicMemberNames(T instance)
|
||||
{
|
||||
return new string[0];
|
||||
return CollectionUtils.ArrayEmpty<string>();
|
||||
}
|
||||
|
||||
public virtual bool TryBinaryOperation(T instance, BinaryOperationBinder binder, object arg, out object result)
|
||||
|
||||
@@ -166,7 +166,7 @@ namespace Newtonsoft.Json.Utilities
|
||||
|
||||
private delegate DynamicMetaObject Fallback(DynamicMetaObject errorSuggestion);
|
||||
|
||||
private static readonly Expression[] NoArgs = new Expression[0];
|
||||
private static Expression[] NoArgs => CollectionUtils.ArrayEmpty<Expression>();
|
||||
|
||||
private static IEnumerable<Expression> GetArgs(params DynamicMetaObject[] args)
|
||||
{
|
||||
|
||||
@@ -158,7 +158,7 @@ namespace Newtonsoft.Json.Utilities
|
||||
|
||||
public override DynamicMetaObject FallbackGetMember(DynamicMetaObject target, DynamicMetaObject errorSuggestion)
|
||||
{
|
||||
DynamicMetaObject retMetaObject = _innerBinder.Bind(target, new DynamicMetaObject[] { });
|
||||
DynamicMetaObject retMetaObject = _innerBinder.Bind(target, CollectionUtils.ArrayEmpty<DynamicMetaObject>());
|
||||
|
||||
NoThrowExpressionVisitor noThrowVisitor = new NoThrowExpressionVisitor();
|
||||
Expression resultExpression = noThrowVisitor.Visit(retMetaObject.Expression);
|
||||
|
||||
@@ -87,40 +87,45 @@ namespace Newtonsoft.Json.Utilities
|
||||
{
|
||||
ParameterInfo[] parametersInfo = method.GetParameters();
|
||||
|
||||
Expression[] argsExpression = new Expression[parametersInfo.Length];
|
||||
IList<ByRefParameter> refParameterMap = new List<ByRefParameter>();
|
||||
|
||||
for (int i = 0; i < parametersInfo.Length; i++)
|
||||
Expression[] argsExpression;
|
||||
IList<ByRefParameter> refParameterMap;
|
||||
if (parametersInfo.Length == 0)
|
||||
{
|
||||
ParameterInfo parameter = parametersInfo[i];
|
||||
Type parameterType = parameter.ParameterType;
|
||||
bool isByRef = false;
|
||||
if (parameterType.IsByRef)
|
||||
argsExpression = CollectionUtils.ArrayEmpty<Expression>();
|
||||
refParameterMap = CollectionUtils.ArrayEmpty<ByRefParameter>();
|
||||
}
|
||||
else
|
||||
{
|
||||
argsExpression = new Expression[parametersInfo.Length];
|
||||
refParameterMap = new List<ByRefParameter>();
|
||||
|
||||
for (int i = 0; i < parametersInfo.Length; i++)
|
||||
{
|
||||
parameterType = parameterType.GetElementType();
|
||||
isByRef = true;
|
||||
}
|
||||
|
||||
Expression indexExpression = Expression.Constant(i);
|
||||
|
||||
Expression paramAccessorExpression = Expression.ArrayIndex(argsParameterExpression, indexExpression);
|
||||
|
||||
Expression argExpression = EnsureCastExpression(paramAccessorExpression, parameterType, !isByRef);
|
||||
|
||||
if (isByRef)
|
||||
{
|
||||
ParameterExpression variable = Expression.Variable(parameterType);
|
||||
refParameterMap.Add(new ByRefParameter
|
||||
ParameterInfo parameter = parametersInfo[i];
|
||||
Type parameterType = parameter.ParameterType;
|
||||
bool isByRef = false;
|
||||
if (parameterType.IsByRef)
|
||||
{
|
||||
Value = argExpression,
|
||||
Variable = variable,
|
||||
IsOut = parameter.IsOut
|
||||
});
|
||||
parameterType = parameterType.GetElementType();
|
||||
isByRef = true;
|
||||
}
|
||||
|
||||
argExpression = variable;
|
||||
Expression indexExpression = Expression.Constant(i);
|
||||
|
||||
Expression paramAccessorExpression = Expression.ArrayIndex(argsParameterExpression, indexExpression);
|
||||
|
||||
Expression argExpression = EnsureCastExpression(paramAccessorExpression, parameterType, !isByRef);
|
||||
|
||||
if (isByRef)
|
||||
{
|
||||
ParameterExpression variable = Expression.Variable(parameterType);
|
||||
refParameterMap.Add(new ByRefParameter {Value = argExpression, Variable = variable, IsOut = parameter.IsOut});
|
||||
|
||||
argExpression = variable;
|
||||
}
|
||||
|
||||
argsExpression[i] = argExpression;
|
||||
}
|
||||
|
||||
argsExpression[i] = argExpression;
|
||||
}
|
||||
|
||||
Expression callExpression;
|
||||
|
||||
@@ -90,7 +90,7 @@ namespace Newtonsoft.Json.Utilities
|
||||
#if !(PORTABLE40 || PORTABLE)
|
||||
EmptyTypes = Type.EmptyTypes;
|
||||
#else
|
||||
EmptyTypes = new Type[0];
|
||||
EmptyTypes = CollectionUtils.ArrayEmpty<Type>();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user