9 namespace Core.TypeCast
12 using System.Reflection;
15 using System.Runtime.CompilerServices;
16 using System.Collections;
17 using System.Collections.Generic;
23 public static partial class ObjectExtension
25 private static Type objectType = typeof(
object);
26 private static TypeInfo objectTypeInfo = typeof(
object).GetTypeInfo();
49 private static bool GetConverterOrDefault<TIn, TOut>(
51 out Converter converter,
53 Type typeArgument = null,
56 bool throwException =
false,
57 bool unboxObjectType =
true,
58 string attributeName = null,
59 bool withContext =
false)
61 ConverterCollection.AutoInitialize();
62 if(typeof(TIn) == objectType)
64 if(throwException ==
true && unboxObjectType ==
false && ConverterCollection.CurrentInstance.Settings.AllowGenericTypes ==
false)
66 throw new ConverterException(
ConverterCause.ConverterTypeInIsExplicitObject);
69 var typeFrom = unboxObjectType ?
self.GetType() : objectType;
70 if(typeTo == null || typeof(TOut) != objectType)
72 typeTo = typeTo ?? typeof(TOut);
74 converter = ConverterCollection.CurrentInstance.Get(typeFrom: typeFrom.GetTypeInfo(), typeTo: typeTo?.GetTypeInfo(), typeArgument: typeArgument?.GetTypeInfo(),
75 typeBase: typeBase?.GetTypeInfo(), attributeName: attributeName, loadOnDemand:
true, assignable:
false, withContext: withContext);
79 converter = ConverterCollection.CurrentInstance.Get(typeFrom: typeFrom.GetTypeInfo(), typeTo: typeTo?.GetTypeInfo(), typeArgument: typeArgument?.GetTypeInfo(),
80 typeBase: typeBase?.GetTypeInfo(), attributeName: attributeName, loadOnDemand:
false, assignable:
true, withContext: withContext);
83 if(converter == null && unboxObjectType ==
true && typeof(TIn) == objectType)
85 converter = ConverterCollection.CurrentInstance.Get(typeFrom: objectTypeInfo, typeTo: typeTo?.GetTypeInfo(), typeArgument: typeArgument?.GetTypeInfo(),
86 typeBase: typeBase?.GetTypeInfo(), attributeName: attributeName, loadOnDemand:
false, assignable:
false, withContext: withContext);
91 converter = ConverterCollection.CurrentInstance.Get<TIn, TOut>(
self, typeArgument: typeArgument, loadOnDemand:
true);
96 result = (TOut)(
object)
self;
100 result =
default(TOut);
117 private static bool InvokeConvert<TIn, TOut>(TIn
self, out TOut result,
object defaultValue,
bool throwException, Converter converter, IConvertContext contextInstance = null, [CallerMemberName]
string caller = null)
119 if(defaultValue is IConvertContext)
121 contextInstance = SetContext<TIn, TOut>(defaultValue as IConvertContext, ((IConvertContext)defaultValue).Value, throwException, converter, caller);
125 contextInstance = SetContext<TIn, TOut>(contextInstance, defaultValue, throwException, converter, caller);
128 if(converter != null)
132 result = (TOut)converter.Convert(
self, contextInstance ?? defaultValue);
133 return IsDefaultValue<TOut>(result) ==
false;
137 if(exc is IException)
139 if(throwException ==
true)
144 else if(exc is System.FormatException)
146 if(throwException ==
true)
151 else if(exc is System.OverflowException || exc is System.InvalidOperationException || exc is System.ArithmeticException)
153 if(throwException ==
true)
165 result =
default(TOut);
167 if(ConverterCollection.CurrentInstance.Settings.AllowDynamicType ==
true)
195 private static IConvertContext SetContext<TIn, TOut>(IConvertContext contextInstance,
object defaultValue,
bool throwException, Converter converter,
string caller)
197 if(contextInstance != null)
199 contextInstance =
new ConvertContext<TIn, TOut>(defaultValue)
201 Argument = defaultValue?.GetType(),
202 Converter = contextInstance.Converter ?? converter,
203 Caller = contextInstance.Caller ?? caller,
204 ThrowExceptions = contextInstance.ThrowExceptions ?? throwException,
205 Nullable = contextInstance.Nullable ??
false 209 return contextInstance;
221 [MethodImpl(MethodImplOptions.AggressiveInlining)]
222 public static bool CanConvertTo<TIn, TOut>(
this TIn
self, TOut target =
default(TOut))
224 TOut result =
default(TOut);
225 Converter converter = null;
226 GetConverterOrDefault<TIn, TOut>(
self, out converter, out result);
227 return converter != null;
240 [MethodImpl(MethodImplOptions.AggressiveInlining)]
241 public static bool CanConvertTo<TOut, TArg>(
this object self, TOut target =
default(TOut), TArg model =
default(TArg))
243 TOut result =
default(TOut);
244 Converter converter = null;
245 GetConverterOrDefault<object, TOut>(
self, out converter, out result, typeArgument: typeof(TArg), unboxObjectType:
true);
246 return converter != null;
259 [MethodImpl(MethodImplOptions.AggressiveInlining)]
260 public static bool CanConvertTo<TIn, TArg>(
this TIn
self, Type typeTo, TArg model =
default(TArg))
262 object result = null;
263 Converter converter = null;
264 GetConverterOrDefault<TIn, object>(
self, out converter, out result, typeTo: typeTo, typeArgument: typeof(TArg));
265 return converter != null;
277 [MethodImpl(MethodImplOptions.AggressiveInlining)]
278 public static bool CanConvertTo<TIn>(
this TIn
self, Type typeTo, Type typeModel)
280 object result = null;
281 Converter converter = null;
282 GetConverterOrDefault<TIn, object>(
self, out converter, out result, typeTo: typeTo, typeArgument: typeModel?.GetType());
283 return converter != null;
294 [MethodImpl(MethodImplOptions.AggressiveInlining)]
295 public static bool CanConvertTo<TIn>(
this TIn
self, Type typeTo)
297 object result = null;
298 Converter converter = null;
299 GetConverterOrDefault<TIn, object>(
self, out converter, out result, typeTo: typeTo, unboxObjectType:
true);
300 return converter != null;
310 [MethodImpl(MethodImplOptions.AggressiveInlining)]
311 public static bool CanConvertTo<TOut>(
this object self)
313 TOut result =
default(TOut);
314 Converter converter = null;
315 GetConverterOrDefault<object, TOut>(
self, out converter, out result, unboxObjectType:
true);
316 return converter != null;
325 [MethodImpl(MethodImplOptions.AggressiveInlining)]
326 public static bool IsDefaultValue<TIn>(
this TIn
self)
328 return Object.Equals(
self,
default(TIn)) ==
true;
337 [MethodImpl(MethodImplOptions.AggressiveInlining)]
338 public static bool IsDefaultValue<TIn>(
this object self)
340 return Object.Equals(
self,
default(TIn)) ==
true;
ConverterCause
Contains the reasons for a ConverterException to be raised.