Пример #1
0
        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);
        }
Пример #2
0
 internal static T Convert <TFrom>(TFrom from)
 {
     return(CastCache <TFrom> .Cast(from));
 }
Пример #3
0
        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);
        }
Пример #4
0
 internal static T Convert <T1>(T1 from)
 {
     return(CastCache <T1> .Convert(from));
 }