// /** // * File: Cast.cs // * Author: haraldwolff // * // * This file and it's content is copyrighted by the Author and / or copyright holder. // * Any use wihtout proper permission is illegal and may lead to legal actions. // * // * // **/ using System; using System.Reflection; using System.Linq; using System.Threading; namespace ln.type { public static class Cast { public static T To(object value) => (T)To(value, typeof(T)); public static object To(object value, Type targetType) { if (Object.ReferenceEquals(null, value)) return null; if (targetType.IsInstanceOfType(value)) return value; object casted; if ( !Implicit(value, targetType, out casted) && !Implicit(value, value.GetType(), targetType, out casted) && !Explicit(value, targetType, out casted) && !Explicit(value, value.GetType(), targetType, out casted) ) { if (targetType.IsEnum) { if (value is string sValue) { casted = Enum.Parse(targetType, sValue); } else { throw new NotSupportedException(); } } else if (targetType.IsArray) { Array array = value as Array; Array castedArray = Array.CreateInstance(targetType.GetElementType(), array.Length); for (int n = 0; n < array.Length; n++) castedArray.SetValue(To(array.GetValue(n), targetType.GetElementType()), n); casted = castedArray; } else { casted = Convert.ChangeType(value, targetType); } } return casted; } public static bool Implicit(object value, Type type, out object casted) => Implicit(value, type, type, out casted); public static bool Implicit(object value, Type type, Type targetType, out object casted) { foreach (MethodInfo methodInfo in type.GetMethods(BindingFlags.Public | BindingFlags.Static)) { if (methodInfo.Name.Equals("op_Implicit") && methodInfo.ReturnType.Equals(targetType)) { ParameterInfo parameterInfo = methodInfo.GetParameters().FirstOrDefault(); if ((parameterInfo != null) && (parameterInfo.ParameterType.Equals(value.GetType()))) { casted = methodInfo.Invoke(null, new object[] { value }); return true; } } } casted = null; return false; } public static bool Explicit(object value, Type type, out object casted) => Implicit(value, type, type, out casted); public static bool Explicit(object value, Type type, Type targetType, out object casted) { foreach (MethodInfo methodInfo in type.GetMethods(BindingFlags.Public | BindingFlags.Static)) { if (methodInfo.Name.Equals("op_Explicit") && methodInfo.ReturnType.Equals(targetType)) { ParameterInfo parameterInfo = methodInfo.GetParameters().FirstOrDefault(); if ((parameterInfo != null) && (parameterInfo.ParameterType.Equals(value.GetType()))) { casted = methodInfo.Invoke(null, new object[] { value }); return true; } } } casted = null; return false; } } }