Browse Source

Merge pull request #2961 from MarchingCube/alloc-typeutilities

Remove closure allocations from TypeUtilities conversion functions.
pull/2989/head
Nikita Tsukanov 7 years ago
committed by GitHub
parent
commit
b9118085e2
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 50
      src/Avalonia.Base/Utilities/TypeUtilities.cs

50
src/Avalonia.Base/Utilities/TypeUtilities.cs

@ -13,7 +13,7 @@ namespace Avalonia.Utilities
/// </summary>
public static class TypeUtilities
{
private static int[] Conversions =
private static readonly int[] Conversions =
{
0b101111111111101, // Boolean
0b100001111111110, // Char
@ -32,7 +32,7 @@ namespace Avalonia.Utilities
0b111111111111111, // String
};
private static int[] ImplicitConversions =
private static readonly int[] ImplicitConversions =
{
0b000000000000001, // Boolean
0b001110111100010, // Char
@ -51,7 +51,7 @@ namespace Avalonia.Utilities
0b100000000000000, // String
};
private static Type[] InbuiltTypes =
private static readonly Type[] InbuiltTypes =
{
typeof(Boolean),
typeof(Char),
@ -70,7 +70,7 @@ namespace Avalonia.Utilities
typeof(String),
};
private static readonly Type[] NumericTypes = new[]
private static readonly Type[] NumericTypes =
{
typeof(Byte),
typeof(Decimal),
@ -188,8 +188,7 @@ namespace Avalonia.Utilities
}
}
var cast = from.GetRuntimeMethods()
.FirstOrDefault(m => (m.Name == "op_Implicit" || m.Name == "op_Explicit") && m.ReturnType == to);
var cast = FindTypeConversionOperatorMethod(from, to, OperatorType.Implicit | OperatorType.Explicit);
if (cast != null)
{
@ -253,8 +252,7 @@ namespace Avalonia.Utilities
}
}
var cast = from.GetRuntimeMethods()
.FirstOrDefault(m => m.Name == "op_Implicit" && m.ReturnType == to);
var cast = FindTypeConversionOperatorMethod(from, to, OperatorType.Implicit);
if (cast != null)
{
@ -335,5 +333,41 @@ namespace Avalonia.Utilities
return NumericTypes.Contains(type);
}
}
[Flags]
private enum OperatorType
{
Implicit = 1,
Explicit = 2
}
private static MethodInfo FindTypeConversionOperatorMethod(Type fromType, Type toType, OperatorType operatorType)
{
const string implicitName = "op_Implicit";
const string explicitName = "op_Explicit";
bool allowImplicit = (operatorType & OperatorType.Implicit) != 0;
bool allowExplicit = (operatorType & OperatorType.Explicit) != 0;
foreach (MethodInfo method in fromType.GetMethods())
{
if (!method.IsSpecialName || method.ReturnType != toType)
{
continue;
}
if (allowImplicit && method.Name == implicitName)
{
return method;
}
if (allowExplicit && method.Name == explicitName)
{
return method;
}
}
return null;
}
}
}

Loading…
Cancel
Save