ln.type/Cast.cs

104 lines
3.8 KiB
C#

// /**
// * 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<T>(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;
}
}
}