Skip to content

Commit 72c9506

Browse files
Added specific types
1 parent 31864be commit 72c9506

12 files changed

+1012
-1074
lines changed

src/Reflector/Cast.cs

+159
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
using System.Globalization;
2+
using System.Reflection;
3+
using VReflector;
4+
5+
namespace Reflector;
6+
7+
8+
public static class Cast
9+
{
10+
private const string ImplicitCastMethodName = "op_Implicit";
11+
private const string ExplicitCastMethodName = "op_Explicit";
12+
13+
public static T? To<T>(object obj) where T : class
14+
{
15+
return obj as T;
16+
}
17+
public static T ToOrDefault<T>(object obj, T defaultValue = default)
18+
{
19+
try
20+
{
21+
return (T)obj;
22+
}
23+
catch
24+
{
25+
return defaultValue;
26+
}
27+
}
28+
public static bool TryTo<T>(object obj, out T? result) where T : class
29+
{
30+
if (obj == null)
31+
{
32+
result = default;
33+
return false;
34+
}
35+
36+
if (obj is T castedObj)
37+
{
38+
result = castedObj;
39+
return true;
40+
}
41+
42+
if (CanExplicit<T>(obj))
43+
{
44+
result = Explicit<T>(obj);
45+
return true;
46+
}
47+
48+
result = default;
49+
return false;
50+
}
51+
public static bool IsCastableTo<T>(object obj)
52+
{
53+
return obj is T || Can<T>(obj.GetType());
54+
}
55+
public static bool CheckCompatibility(Type sourceType, Type targetType)
56+
{
57+
return IsType.AssignableTo(targetType, sourceType) || IsType.AssignableTo(sourceType, targetType);
58+
}
59+
public static bool CanConvert(object source, object target, Type sourceType, Type targetType)
60+
{
61+
try
62+
{
63+
var converted = ConvertTo(source, targetType);
64+
65+
return source.Equals(ConvertTo(converted, sourceType))
66+
&& converted.Equals(target);
67+
}
68+
catch
69+
{
70+
// Ignored
71+
return false;
72+
}
73+
}
74+
public static bool Can<T>(Type baseType)
75+
{
76+
if (baseType is null)
77+
{
78+
return false;
79+
}
80+
return CanExplicit<T>(baseType) || CanExplicit<T>(baseType);
81+
}
82+
public static bool Can<T>(object obj)
83+
{
84+
return Can<T>(obj.GetType());
85+
}
86+
public static T It<T>(object obj)
87+
{
88+
try
89+
{
90+
return (T)obj;
91+
}
92+
catch (InvalidCastException)
93+
{
94+
if (CanImplicit<T>(obj))
95+
return Implicit<T>(obj);
96+
if (CanExplicit<T>(obj))
97+
return Explicit<T>(obj);
98+
else
99+
throw;
100+
}
101+
}
102+
private static bool CanImplicit<T>(Type baseType)
103+
{
104+
return Can<T>(baseType, ImplicitCastMethodName);
105+
}
106+
private static bool CanImplicit<T>(object obj)
107+
{
108+
var baseType = obj.GetType();
109+
return CanImplicit<T>(baseType);
110+
}
111+
private static bool CanExplicit<T>(Type baseType)
112+
{
113+
return Can<T>(baseType, ExplicitCastMethodName);
114+
}
115+
private static bool CanExplicit<T>(object obj)
116+
{
117+
var baseType = obj.GetType();
118+
return CanExplicit<T>(baseType);
119+
}
120+
private static bool Can<T>(Type baseType, string castMethodName)
121+
{
122+
var targetType = typeof(T);
123+
return baseType.GetMethods(BindingFlags.Public | BindingFlags.Static)
124+
.Where(mi => mi.Name == castMethodName && mi.ReturnType == targetType)
125+
.Any(mi =>
126+
{
127+
ParameterInfo? pi = mi.GetParameters().FirstOrDefault();
128+
return pi != null && pi.ParameterType == baseType;
129+
});
130+
}
131+
private static T Implicit<T>(object obj)
132+
{
133+
return To<T>(obj, ImplicitCastMethodName);
134+
}
135+
private static T Explicit<T>(object obj)
136+
{
137+
return To<T>(obj, ExplicitCastMethodName);
138+
}
139+
private static T To<T>(object obj, string castMethodName)
140+
{
141+
var objType = obj.GetType();
142+
MethodInfo conversionMethod = objType.GetMethods(BindingFlags.Public | BindingFlags.Static)
143+
.Where(mi => mi.Name == castMethodName && mi.ReturnType == typeof(T))
144+
.SingleOrDefault(mi =>
145+
{
146+
ParameterInfo? pi = mi.GetParameters().FirstOrDefault();
147+
return pi != null && pi.ParameterType == objType;
148+
});
149+
if (conversionMethod != null)
150+
return (T)conversionMethod.Invoke(null, new[] { obj })!;
151+
else
152+
throw new InvalidCastException($"No method to cast {objType.FullName} to {typeof(T).FullName}");
153+
}
154+
private static object ConvertTo(object source, Type targetType)
155+
{
156+
return Convert.ChangeType(source, targetType, CultureInfo.InvariantCulture);
157+
}
158+
}
159+

src/Reflector/CastExtensions.cs

-207
This file was deleted.

0 commit comments

Comments
 (0)