public static unsafe object IsInstanceOfArray(object obj, void *pvTargetType) { if (obj == null) { return(null); } EEType *pTargetType = (EEType *)pvTargetType; EEType *pObjType = obj.EEType; // Debug.Assert(pTargetType->IsArray, "IsInstanceOfArray called with non-array EEType"); // Debug.Assert(!pTargetType->IsCloned, "cloned array types are disallowed"); // if the types match, we are done if (pObjType == pTargetType) { return(obj); } // if the object is not an array, we're done if (!pObjType->IsArray) { return(null); } // Debug.Assert(!pObjType->IsCloned, "cloned array types are disallowed"); // compare the array types structurally if (pObjType->ParameterizedTypeShape != pTargetType->ParameterizedTypeShape) { // If the shapes are different, there's one more case to check for: Casting SzArray to MdArray rank 1. if (!pObjType->IsSzArray || pTargetType->ArrayRank != 1) { return(null); } } if (CastCache.AreTypesAssignableInternal(pObjType->RelatedParameterType, pTargetType->RelatedParameterType, AssignmentVariation.AllowSizeEquivalence, null)) { return(obj); } return(null); }
internal static T Convert <TFrom>(TFrom from) { return(CastCache <TFrom> .Cast(from)); }
public static bool IsCastableTo(this Type from, Type to) { // from http://www.codeducky.org/10-utilities-c-developers-should-know-part-one/ Throw.IfNull(from, "from"); Throw.IfNull(to, "to"); // explicit conversion always works if to : from OR if // there's an implicit conversion if (from.IsAssignableFrom(to) || from.IsImplicitlyCastableTo(to)) { return(true); } var key = new KeyValuePair <Type, Type>(from, to); if (CastCache.TryGetCachedValue(key, out var cachedValue)) { return(cachedValue); } // for nullable types, we can simply strip off the nullability and evaluate the underyling types var underlyingFrom = Nullable.GetUnderlyingType(from); var underlyingTo = Nullable.GetUnderlyingType(to); if (underlyingFrom != null || underlyingTo != null) { return((underlyingFrom ?? from).IsCastableTo(underlyingTo ?? to)); } bool result; if (from.GetTypeInfo().IsValueType) { try { Helpers.GetMethod(() => AttemptExplicitCast <object, object>()) .GetGenericMethodDefinition() .MakeGenericMethod(from, to) .Invoke(null, new object[0]); result = true; } catch (TargetInvocationException ex) { result = !( ex.InnerException is RuntimeBinderException // if the code runs in an environment where this message is localized, we could attempt a known failure first and base the regex on it's message && Regex.IsMatch(ex.InnerException.Message, @"^Cannot convert type '.*' to '.*'$") ); } } else { // if the from type is null, the dynamic logic above won't be of any help because // either both types are nullable and thus a runtime cast of null => null will // succeed OR we get a runtime failure related to the inability to cast null to // the desired type, which may or may not indicate an actual issue. thus, we do // the work manually result = from.GetTypeInfo().IsNonValueTypeExplicitlyCastableTo(to.GetTypeInfo()); } CastCache.UpdateCache(key, result); return(result); }
internal static T Convert <T1>(T1 from) { return(CastCache <T1> .Convert(from)); }