Display conditions - Loosened up type rules for dynamic comparisons

Display conditions - Improved static value input and added support for int and double
This commit is contained in:
Robert committed 2020-07-07 19:53:24 +02:00
1 parent 913cfd2824
commit 3639185171
21 files changed
+197 -172

No files matched your search

@@ -1,9 +1,25 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
namespace Artemis.Core.Extensions
{
public static class TypeExtensions
{
private static readonly Dictionary<Type, List<Type>> PrimitiveTypeConversions = new Dictionary<Type, List<Type>>
{
{typeof(decimal), new List<Type> {typeof(sbyte), typeof(byte), typeof(short), typeof(ushort), typeof(int), typeof(uint), typeof(long), typeof(ulong), typeof(char)}},
{typeof(double), new List<Type> {typeof(sbyte), typeof(byte), typeof(short), typeof(ushort), typeof(int), typeof(uint), typeof(long), typeof(ulong), typeof(char), typeof(float)}},
{typeof(float), new List<Type> {typeof(sbyte), typeof(byte), typeof(short), typeof(ushort), typeof(int), typeof(uint), typeof(long), typeof(ulong), typeof(char), typeof(float)}},
{typeof(ulong), new List<Type> {typeof(byte), typeof(ushort), typeof(uint), typeof(char)}},
{typeof(long), new List<Type> {typeof(sbyte), typeof(byte), typeof(short), typeof(ushort), typeof(int), typeof(uint), typeof(char)}},
{typeof(uint), new List<Type> {typeof(byte), typeof(ushort), typeof(char)}},
{typeof(int), new List<Type> {typeof(sbyte), typeof(byte), typeof(short), typeof(ushort), typeof(char)}},
{typeof(ushort), new List<Type> {typeof(byte), typeof(char)}},
{typeof(short), new List<Type> {typeof(byte)}}
};
public static bool IsGenericType(this Type type, Type genericType)
{
if (type == null)
@@ -17,6 +33,21 @@ namespace Artemis.Core.Extensions
return source.IsValueType && !source.IsPrimitive && !source.IsEnum;
}
public static bool TypeIsNumber(this Type type)
{
return type == typeof(sbyte)
|| type == typeof(byte)
|| type == typeof(short)
|| type == typeof(ushort)
|| type == typeof(int)
|| type == typeof(uint)
|| type == typeof(long)
|| type == typeof(ulong)
|| type == typeof(float)
|| type == typeof(double)
|| type == typeof(decimal);
}
public static bool IsNumber(this object value)
{
return value is sbyte
@@ -31,5 +62,29 @@ namespace Artemis.Core.Extensions
|| value is double
|| value is decimal;
}
// From https://stackoverflow.com/a/2224421/5015269 but inverted and renamed to match similar framework methods
/// <summary>
/// Determines whether an instance of a specified type can be casted to a variable of the current type
/// </summary>
/// <param name="to"></param>
/// <param name="from"></param>
/// <returns></returns>
public static bool IsCastableFrom(this Type to, Type from)
{
if (to.TypeIsNumber() && from.TypeIsNumber())
return true;
if (to.IsAssignableFrom(from))
return true;
if (PrimitiveTypeConversions.ContainsKey(to) && PrimitiveTypeConversions[to].Contains(from))
return true;
var castable = from.GetMethods(BindingFlags.Public | BindingFlags.Static)
.Any(
m => m.ReturnType == to &&
(m.Name == "op_Implicit" ||
m.Name == "op_Explicit")
);
return castable;
}
}
}