BadScript 2
Loading...
Searching...
No Matches
CastExtensions.cs
Go to the documentation of this file.
1using System;
2using System.Linq;
3using System.Reflection;
4
5namespace CommandLine
6{
7 internal static class CastExtensions
8 {
9 private const string ImplicitCastMethodName = "op_Implicit";
10 private const string ExplicitCastMethodName = "op_Explicit";
11
12 public static bool CanCast<T>(this Type baseType)
13 {
14 return baseType.CanImplicitCast<T>() || baseType.CanExplicitCast<T>();
15 }
16
17 public static bool CanCast<T>(this object obj)
18 {
19 Type objType = obj.GetType();
20
21 return objType.CanCast<T>();
22 }
23
24 public static T Cast<T>(this object obj)
25 {
26 try
27 {
28 return (T)obj;
29 }
30 catch (InvalidCastException)
31 {
32 if (obj.CanImplicitCast<T>())
33 {
34 return obj.ImplicitCast<T>();
35 }
36
37 if (obj.CanExplicitCast<T>())
38 {
39 return obj.ExplicitCast<T>();
40 }
41
42 throw;
43 }
44 }
45
46 private static bool CanImplicitCast<T>(this Type baseType)
47 {
48 return baseType.CanCast<T>(ImplicitCastMethodName);
49 }
50
51 private static bool CanImplicitCast<T>(this object obj)
52 {
53 Type baseType = obj.GetType();
54
55 return baseType.CanImplicitCast<T>();
56 }
57
58 private static bool CanExplicitCast<T>(this Type baseType)
59 {
60 return baseType.CanCast<T>(ExplicitCastMethodName);
61 }
62
63 private static bool CanExplicitCast<T>(this object obj)
64 {
65 Type baseType = obj.GetType();
66
67 return baseType.CanExplicitCast<T>();
68 }
69
70 private static bool CanCast<T>(this Type baseType, string castMethodName)
71 {
72 Type targetType = typeof(T);
73
74 return baseType.GetMethods(BindingFlags.Public | BindingFlags.Static)
75 .Where(mi => mi.Name == castMethodName && mi.ReturnType == targetType)
76 .Any(mi =>
77 {
78 ParameterInfo pi = mi.GetParameters()
79 .FirstOrDefault();
80
81 return pi != null && pi.ParameterType == baseType;
82 }
83 );
84 }
85
86 private static T ImplicitCast<T>(this object obj)
87 {
88 return obj.Cast<T>(ImplicitCastMethodName);
89 }
90
91 private static T ExplicitCast<T>(this object obj)
92 {
93 return obj.Cast<T>(ExplicitCastMethodName);
94 }
95
96 private static T Cast<T>(this object obj, string castMethodName)
97 {
98 Type objType = obj.GetType();
99
100 MethodInfo conversionMethod = objType.GetMethods(BindingFlags.Public | BindingFlags.Static)
101 .Where(mi => mi.Name == castMethodName && mi.ReturnType == typeof(T))
102 .SingleOrDefault(mi =>
103 {
104 ParameterInfo pi = mi.GetParameters()
105 .FirstOrDefault();
106
107 return pi != null && pi.ParameterType == objType;
108 }
109 );
110
111 if (conversionMethod != null)
112 {
113 return (T)conversionMethod.Invoke(null,
114 new[] { obj }
115 );
116 }
117
118 throw new InvalidCastException($"No method to cast {objType.FullName} to {typeof(T).FullName}");
119 }
120 }
121}
const string ExplicitCastMethodName
static bool CanExplicitCast< T >(this Type baseType)
const string ImplicitCastMethodName
static bool CanCast< T >(this Type baseType)
static T Cast< T >(this object obj)
static bool CanImplicitCast< T >(this Type baseType)
static T ImplicitCast< T >(this object obj)
static T ExplicitCast< T >(this object obj)