IsAssignableFrom() public method

public IsAssignableFrom ( Type type ) : bool
type Type
return bool
Ejemplo n.º 1
0
        internal static bool IsAssignableFrom(Type target, Type type)
        {
#if WINRT
            return target.GetTypeInfo().IsAssignableFrom(type.GetTypeInfo());
#else
            return target.IsAssignableFrom(type);
#endif
        }
Ejemplo n.º 2
0
        public static bool IsAssignableFrom(Type t, Type @from)
        {
            if (t == null)
            {
                throw new ArgumentNullException(nameof(t));
            }
#if FEAT_IKVM
            return(IsAssignableFrom(t.FullName, @from));
#else
            return(t.IsAssignableFrom(@from));
#endif
        }
Ejemplo n.º 3
0
        private Type MergeTypes(Type type, Type newType)
        {
            if (type == null)
            {
                return(newType);
            }
            else if (newType == null)
            {
                return(type);
            }
            else if (newType.IsAssignableFrom(type))
            {
                return(newType);
            }
            else if (type.IsAssignableFrom(newType))
            {
                return(type);
            }
            else if (type.IsClass && newType.IsClass)
            {
                var ss = type.GetTypeChain().Reverse();    // System.Object, ..., X, ..., type
                var ts = newType.GetTypeChain().Reverse(); // System.Object, ..., Y, ..., newType

                return(Enumerable
                       .Zip(ss, ts, Tuple.Create)
                       .Where(t => t.Item1 == t.Item2)
                       .Last()
                       .Item1);
            }
            else if (type == types.Boolean && (newType == types.Int32 || newType == types.Int64))
            {
                return(newType);
            }
            else if (newType == types.Boolean && (type == types.Int32 || type == types.Int64))
            {
                return(type);
            }
            else if (
                (type == types.UInt32 && newType == types.Int32) ||
                (type == types.Int32 && newType == types.UInt32))
            {
                return(newType);
            }
            else
            {
                throw new InvalidOperationException("Cannot determine type");
            }
        }
Ejemplo n.º 4
0
        public bool IsValidSubType(Type subType)
        {
#if WINRT
            if (!CanHaveSubType(_typeInfo))
            {
                return(false);
            }
#else
            if (!CanHaveSubType(Type))
            {
                return(false);
            }
#endif
#if WINRT
            return(_typeInfo.IsAssignableFrom(subType.GetTypeInfo()));
#else
            return(Type.IsAssignableFrom(subType));
#endif
        }
Ejemplo n.º 5
0
        public TypeSerializer(TypeModel model, Type forType, int[] fieldNumbers, IProtoSerializer[] serializers, MethodInfo[] baseCtorCallbacks, bool isRootType, bool useConstructor, CallbackSet callbacks, Type constructType, MethodInfo factory)
        {
            Helpers.DebugAssert(forType != null);
            Helpers.DebugAssert(fieldNumbers != null);
            Helpers.DebugAssert(serializers != null);
            Helpers.DebugAssert(fieldNumbers.Length == serializers.Length);

            Helpers.Sort(fieldNumbers, serializers);
            bool hasSubTypes = false;

            for (int i = 1; i < fieldNumbers.Length; i++)
            {
                if (fieldNumbers[i] == fieldNumbers[i - 1])
                {
                    throw new InvalidOperationException("Duplicate field-number detected; " +
                                                        fieldNumbers[i].ToString() + " on: " + forType.FullName);
                }
                if (!hasSubTypes && serializers[i].ExpectedType != forType)
                {
                    hasSubTypes = true;
                }
            }
            this.forType = forType;
            this.factory = factory;
#if WINRT
            this.typeInfo = forType.GetTypeInfo();
#endif
            if (constructType == null)
            {
                constructType = forType;
            }
            else
            {
#if WINRT
                if (!typeInfo.IsAssignableFrom(constructType.GetTypeInfo()))
#else
                if (!forType.IsAssignableFrom(constructType))
#endif
                {
                    throw new InvalidOperationException(forType.FullName + " cannot be assigned from " + constructType.FullName);
                }
            }
            this.constructType  = constructType;
            this.serializers    = serializers;
            this.fieldNumbers   = fieldNumbers;
            this.callbacks      = callbacks;
            this.isRootType     = isRootType;
            this.useConstructor = useConstructor;

            if (baseCtorCallbacks != null && baseCtorCallbacks.Length == 0)
            {
                baseCtorCallbacks = null;
            }
            this.baseCtorCallbacks = baseCtorCallbacks;
#if !NO_GENERICS
            if (Helpers.GetUnderlyingType(forType) != null)
            {
                throw new ArgumentException("Cannot create a TypeSerializer for nullable types", "forType");
            }
#endif

#if WINRT
            if (iextensible.IsAssignableFrom(typeInfo))
            {
                if (typeInfo.IsValueType || !isRootType || hasSubTypes)
#else
            if (model.MapType(iextensible).IsAssignableFrom(forType))
            {
                if (forType.IsValueType || !isRootType || hasSubTypes)
#endif
                {
                    throw new NotSupportedException("IExtensible is not supported in structs or classes with inheritance");
                }
                isExtensible = true;
            }
#if WINRT
            TypeInfo constructTypeInfo = constructType.GetTypeInfo();
            hasConstructor = !constructTypeInfo.IsAbstract && Helpers.GetConstructor(constructTypeInfo, Helpers.EmptyTypes, true) != null;
#else
            hasConstructor = !constructType.IsAbstract && Helpers.GetConstructor(constructType, Helpers.EmptyTypes, true) != null;
#endif
            if (constructType != forType && useConstructor && !hasConstructor)
            {
                throw new ArgumentException("The supplied default implementation cannot be created: " + constructType.FullName, "constructType");
            }
        }
Ejemplo n.º 6
0
        MethodInfo GetEnumeratorInfo(TypeModel model, out MethodInfo moveNext, out MethodInfo current)
        {
#if WINRT
            TypeInfo enumeratorType = null, iteratorType, expectedType = ExpectedType.GetTypeInfo();
#else
            Type enumeratorType = null, iteratorType, expectedType = ExpectedType;
#endif

            // try a custom enumerator
            MethodInfo getEnumerator = Helpers.GetInstanceMethod(expectedType, "GetEnumerator", null);
            Type       itemType      = Tail.ExpectedType;

            if (getEnumerator != null)
            {
                iteratorType = getEnumerator.ReturnType
#if WINRT
                               .GetTypeInfo()
#endif
                ;
                moveNext = Helpers.GetInstanceMethod(iteratorType, "MoveNext", null);
                PropertyInfo prop = Helpers.GetProperty(iteratorType, "Current");
                current = prop == null ? null : Helpers.GetGetMethod(prop, false);
                if (moveNext == null && (model.MapType(ienumeratorType).IsAssignableFrom(iteratorType)))
                {
                    moveNext = Helpers.GetInstanceMethod(model.MapType(ienumeratorType), "MoveNext", null);
                }
                // fully typed
                if (moveNext != null && moveNext.ReturnType == model.MapType(typeof(bool)) &&
                    current != null && current.ReturnType == itemType)
                {
                    return(getEnumerator);
                }
                moveNext = current = getEnumerator = null;
            }

#if !NO_GENERICS
            // try IEnumerable<T>
            Type tmp = model.MapType(typeof(System.Collections.Generic.IEnumerable <>), false);

            if (tmp != null)
            {
                tmp = tmp.MakeGenericType(itemType);

#if WINRT
                enumeratorType = tmp.GetTypeInfo();
#else
                enumeratorType = tmp;
#endif
            }
            ;
            if (enumeratorType != null && enumeratorType.IsAssignableFrom(expectedType))
            {
                getEnumerator = Helpers.GetInstanceMethod(enumeratorType, "GetEnumerator");

#if WINRT
                iteratorType = getEnumerator.ReturnType.GetTypeInfo();
#else
                iteratorType = getEnumerator.ReturnType;
#endif

                moveNext = Helpers.GetInstanceMethod(model.MapType(ienumeratorType), "MoveNext");
                current  = Helpers.GetGetMethod(Helpers.GetProperty(iteratorType, "Current"), false);
                return(getEnumerator);
            }
#endif
            // give up and fall-back to non-generic IEnumerable
            enumeratorType = model.MapType(ienumerableType);
            getEnumerator  = Helpers.GetInstanceMethod(enumeratorType, "GetEnumerator");
            iteratorType   = getEnumerator.ReturnType
#if WINRT
                             .GetTypeInfo()
#endif
            ;
            moveNext = Helpers.GetInstanceMethod(iteratorType, "MoveNext");
            current  = Helpers.GetGetMethod(Helpers.GetProperty(iteratorType, "Current"), false);
            return(getEnumerator);
        }
Ejemplo n.º 7
0
 public Local GetLocalWithValue(Type type, Compiler.Local fromValue)
 {
     if (fromValue != null)
     {
         if (fromValue.Type == type) return fromValue.AsCopy();
         // otherwise, load onto the stack and let the default handling (below) deal with it
         LoadValue(fromValue);
         if (!type.IsValueType && (fromValue.Type == null || !type.IsAssignableFrom(fromValue.Type)))
         { // need to cast
             Cast(type);
         }
     }
     // need to store the value from the stack
     Local result = new Local(this, type);
     StoreValue(result);
     return result;
 }
Ejemplo n.º 8
0
        public static Conversion GetExplicit(Operand op, Type to, bool onlyStandard, ITypeMapper typeMapper)
        {
            // try implicit
            Conversion conv = GetImplicit(op, to, onlyStandard, typeMapper);

            if (conv.IsValid)
            {
                return(conv);
            }

            Type from = Operand.GetType(op, typeMapper);

            Type fromUnderlying = Helpers.GetNullableUnderlyingType(@from);

            if (fromUnderlying == to)
            {
                return(new UnwrapNullable(typeMapper));
            }


            Type toUnderlying = Helpers.GetNullableUnderlyingType(to);

            if (toUnderlying != null && fromUnderlying != null)
            {
                var c = GetExplicit(new FakeTypedOperand(fromUnderlying), toUnderlying, onlyStandard, typeMapper);
                if (c.IsValid)
                {
                    return(new ConvertNullable(typeMapper, c));
                }
            }


            // section 6.3.2 - Standard explicit conversions
            if (onlyStandard)
            {
                if (from == null || !GetImplicit(to, @from, true, typeMapper).IsValid)
                {
                    return(new Invalid(typeMapper));
                }
            }

            TypeCode tcFrom = Type.GetTypeCode(from);
            TypeCode tcTo   = Type.GetTypeCode(to);
            byte     ct     = _convTable[(int)tcFrom][(int)tcTo];

            // section 6.2.1 - Explicit numeric conversions, 6.2.2 - Explicit enumeration conversions
            if ((from.IsPrimitive || from.IsEnum || Helpers.AreTypesEqual(from, typeof(decimal), typeMapper)) && (to.IsPrimitive || to.IsEnum || Helpers.AreTypesEqual(to, typeof(decimal), typeMapper)))
            {
                if (ct == D)
                {
                    return(new Direct(typeMapper));                     // this can happen for conversions involving enum-s
                }
                if (ct <= E)
                {
                    if (Helpers.AreTypesEqual(from, typeof(decimal), typeMapper) || Helpers.AreTypesEqual(to, typeof(decimal), typeMapper))
                    {
                        // decimal is handled as user-defined conversion, but as it is a standard one, always enable UDC processing
                        onlyStandard = false;
                    }
                    else
                    {
                        return(new Primitive(typeMapper));
                    }
                }
            }

            // section 6.2.5 - User-defined explicit conversions (details in section 6.4.4)
            if (!(onlyStandard || Helpers.AreTypesEqual(from, typeof(object), typeMapper) || Helpers.AreTypesEqual(to, typeof(object), typeMapper) || from.IsInterface || to.IsInterface ||
                  to.IsSubclassOf(from) || from.IsSubclassOf(to)))
            {
                List <UserDefined> candidates = null;
                FindCandidates(ref candidates, FindExplicitMethods(from, to, typeMapper), op, to, GetExplicit, typeMapper);

                if (candidates != null)
                {
                    if (candidates.Count == 1)
                    {
                        return(candidates[0]);
                    }

                    return(UserDefined.FindExplicit(candidates, @from, to, typeMapper));
                }
            }

            // section 6.2.3 - Explicit reference conversions, 6.2.4 - Unboxing conversions
            // TODO: not really according to spec, but mostly works
            if (!from.IsValueType && from.IsAssignableFrom(to))
            {
                if (to.IsValueType)
                {
                    return(new Unboxing(typeMapper));
                }
                else
                {
                    return(new Cast(typeMapper));
                }
            }

            return(new Invalid(typeMapper));
        }
Ejemplo n.º 9
0
        // the sections mentioned in comments of this method are from C# specification v1.2
        public static Conversion GetImplicit(Operand op, Type to, bool onlyStandard, ITypeMapper typeMapper)
        {
            Type from = Operand.GetType(op, typeMapper);

            Type toUnderlying = Helpers.GetNullableUnderlyingType(to);

            if (to.Equals(from))
            {
                return(new Direct(typeMapper));
            }

            Type fromUnderlying = Helpers.GetNullableUnderlyingType(@from);

            if (toUnderlying != null)
            {
                if (fromUnderlying != null)
                {
                    Conversion c = GetImplicit(new FakeTypedOperand(fromUnderlying), toUnderlying, onlyStandard, typeMapper);
                    if (c.IsValid)
                    {
                        return(new ConvertNullable(typeMapper, c));
                    }
                }
                else
                {
                    Conversion c = GetImplicit(op, toUnderlying, onlyStandard, typeMapper);
                    if (c.IsValid)
                    {
                        return(new WrapNullable(typeMapper, c));
                    }
                }
            }

            // required for arrays created from TypeBuilder-s
            if (from != null && to.IsArray && from.IsArray)
            {
                if (to.GetArrayRank() == from.GetArrayRank())
                {
                    if (to.GetElementType().Equals(from.GetElementType()))
                    {
                        return(new Direct(typeMapper));
                    }
                }
            }

            TypeCode tcFrom = Type.GetTypeCode(from);
            TypeCode tcTo   = Type.GetTypeCode(to);
            byte     ct     = _convTable[(int)tcFrom][(int)tcTo];

            // section 6.1.2 - Implicit numeric conversions
            if (from != null && (from.IsPrimitive || Helpers.AreTypesEqual(from, typeof(decimal), typeMapper)) && (to.IsPrimitive || Helpers.AreTypesEqual(to, typeof(decimal), typeMapper)))
            {
                if (ct <= I)
                {
                    if (Helpers.AreTypesEqual(from, typeof(decimal), typeMapper) || Helpers.AreTypesEqual(to, typeof(decimal), typeMapper))
                    {
                        // decimal is handled as user-defined conversion, but as it is a standard one, always enable UDC processing
                        onlyStandard = false;
                    }
                    else
                    {
                        return(new Primitive(typeMapper));
                    }
                }
            }

            IntLiteral intLit = op as IntLiteral;

            // section 6.1.3 - Implicit enumeration conversions
            if (!onlyStandard && to.IsEnum && (object)intLit != null && intLit.Value == 0)
            {
                return(new Primitive(typeMapper));
            }

            // section 6.1.4 - Implicit reference conversions
            if ((from == null || !from.IsValueType) && !to.IsValueType)
            {
                if (from == null)                 // from the null type to any reference type
                {
                    return(new Direct(typeMapper));
                }

                if (to.IsAssignableFrom(from))                  // the rest
                {
                    return(new Direct(typeMapper));
                }
            }

            if (from == null)                   // no other conversion from null type is possible
            {
                return(new Invalid(typeMapper));
            }

            // section 6.1.5 - Boxing conversions
            if (from.IsValueType)
            {
                if (to.IsAssignableFrom(from))
                {
                    return(new Boxing(typeMapper));
                }
            }

            // section 6.1.6 - Implicit constant expression conversions
            if ((object)intLit != null && Helpers.AreTypesEqual(from, typeof(int), typeMapper) && to.IsPrimitive)
            {
                int val = intLit.Value;

                switch (tcTo)
                {
                case TypeCode.SByte:
                    if (val >= sbyte.MinValue && val <= sbyte.MaxValue)
                    {
                        return(new Direct(typeMapper));
                    }
                    break;

                case TypeCode.Byte:
                    if (val >= byte.MinValue && val <= byte.MaxValue)
                    {
                        return(new Direct(typeMapper));
                    }
                    break;

                case TypeCode.Int16:
                    if (val >= short.MinValue && val <= short.MaxValue)
                    {
                        return(new Direct(typeMapper));
                    }
                    break;

                case TypeCode.UInt16:
                    if (val >= ushort.MinValue && val <= ushort.MaxValue)
                    {
                        return(new Direct(typeMapper));
                    }
                    break;

                case TypeCode.UInt32:
                    if (val >= 0)
                    {
                        return(new Direct(typeMapper));
                    }
                    break;

                case TypeCode.UInt64:
                    if (val >= 0)
                    {
                        return(new Direct(typeMapper));
                    }
                    break;
                }
            }

            // section 6.1.7 - User-defined implicit conversions (details in section 6.4.3)
            if (onlyStandard || Helpers.AreTypesEqual(from, typeof(object), typeMapper) || Helpers.AreTypesEqual(to, typeof(object), typeMapper) || from.IsInterface || to.IsInterface ||
                to.IsSubclassOf(from) || from.IsSubclassOf(to))
            {
                return(new Invalid(typeMapper));  // skip not-permitted conversion attempts (section 6.4.1)
            }
            List <UserDefined> candidates = null;

            FindCandidates(ref candidates, FindImplicitMethods(from, to, typeMapper), op, to, GetImplicit, typeMapper);

            if (candidates == null)
            {
                return(new Invalid(typeMapper));
            }

            if (candidates.Count == 1)
            {
                return(candidates[0]);
            }

            return(UserDefined.FindImplicit(candidates, @from, to, typeMapper));
        }
Ejemplo n.º 10
0
        // the sections mentioned in comments of this method are from C# specification v1.2
		public static Conversion GetImplicit(Operand op, Type to, bool onlyStandard, ITypeMapper typeMapper)
		{
			Type from = Operand.GetType(op, typeMapper);

            Type toUnderlying = Helpers.GetNullableUnderlyingType(to);
		    if (to.Equals(from))
		        return new Direct(typeMapper);

            Type fromUnderlying = Helpers.GetNullableUnderlyingType(@from);
		    if (toUnderlying != null)
		    {
		        if (fromUnderlying != null)
		        {
		            Conversion c = GetImplicit(new FakeTypedOperand(fromUnderlying), toUnderlying, onlyStandard, typeMapper);
		            if (c.IsValid) return new ConvertNullable(typeMapper, c);
		        }
		        else
		        {
                    Conversion c = GetImplicit(op, toUnderlying, onlyStandard, typeMapper);
                    if (c.IsValid) return new WrapNullable(typeMapper, c);
                }
		    }
            
		    // required for arrays created from TypeBuilder-s
			if (from != null && to.IsArray && from.IsArray)
			{
				if (to.GetArrayRank() == from.GetArrayRank())
				{
					if (to.GetElementType().Equals(from.GetElementType()))
						return new Direct(typeMapper);
				}
			}

			TypeCode tcFrom = Type.GetTypeCode(from);
			TypeCode tcTo = Type.GetTypeCode(to);
			byte ct = _convTable[(int)tcFrom][(int)tcTo];

			// section 6.1.2 - Implicit numeric conversions
			if (from != null && (from.IsPrimitive || Helpers.AreTypesEqual(from, typeof(decimal), typeMapper)) && (to.IsPrimitive || Helpers.AreTypesEqual(to, typeof(decimal), typeMapper)))
			{
				if (ct <= I)
				{
				    if (Helpers.AreTypesEqual(from, typeof(decimal), typeMapper) || Helpers.AreTypesEqual(to, typeof(decimal), typeMapper))
						// decimal is handled as user-defined conversion, but as it is a standard one, always enable UDC processing
						onlyStandard = false;
					else
						return new Primitive(typeMapper);
				}
			}

			IntLiteral intLit = op as IntLiteral;

			// section 6.1.3 - Implicit enumeration conversions
			if (!onlyStandard && to.IsEnum && (object)intLit != null && intLit.Value == 0)
				return new Primitive(typeMapper);

			// section 6.1.4 - Implicit reference conversions
			if ((from == null || !from.IsValueType) && !to.IsValueType)
			{
				if (from == null) // from the null type to any reference type
					return new Direct(typeMapper);

				if (to.IsAssignableFrom(from))	// the rest
					return new Direct(typeMapper);
			}

			if (from == null)	// no other conversion from null type is possible
				return new Invalid(typeMapper);

			// section 6.1.5 - Boxing conversions
			if (from.IsValueType)
			{
				if (to.IsAssignableFrom(from))
					return new Boxing(typeMapper);
			}

			// section 6.1.6 - Implicit constant expression conversions
			if ((object)intLit != null && Helpers.AreTypesEqual(from, typeof(int), typeMapper) && to.IsPrimitive)
			{
				int val = intLit.Value;

				switch (tcTo)
				{
					case TypeCode.SByte:
						if (val >= sbyte.MinValue && val <= sbyte.MaxValue)
							return new Direct(typeMapper);
						break;
					case TypeCode.Byte:
						if (val >= byte.MinValue && val <= byte.MaxValue)
                            return new Direct(typeMapper);
                        break;
					case TypeCode.Int16:
						if (val >= short.MinValue && val <= short.MaxValue)
                            return new Direct(typeMapper);
                        break;
					case TypeCode.UInt16:
						if (val >= ushort.MinValue && val <= ushort.MaxValue)
                            return new Direct(typeMapper);
                        break;
					case TypeCode.UInt32:
						if (val >= 0)
                            return new Direct(typeMapper);
                        break;
					case TypeCode.UInt64:
						if (val >= 0)
                            return new Direct(typeMapper);
                        break;
				}
			}

			// section 6.1.7 - User-defined implicit conversions (details in section 6.4.3)
			if (onlyStandard || Helpers.AreTypesEqual(from, typeof(object), typeMapper) || Helpers.AreTypesEqual(to, typeof(object), typeMapper) || from.IsInterface || to.IsInterface ||
				to.IsSubclassOf(from) || from.IsSubclassOf(to))
                return new Invalid(typeMapper);  // skip not-permitted conversion attempts (section 6.4.1)

            List<UserDefined> candidates = null;
			FindCandidates(ref candidates, FindImplicitMethods(from, to, typeMapper), op, to, GetImplicit, typeMapper);

			if (candidates == null)
                return new Invalid(typeMapper);

            if (candidates.Count == 1)
				return candidates[0];

			return UserDefined.FindImplicit(candidates, @from, to, typeMapper);
		}
Ejemplo n.º 11
0
        internal static MethodInfo ResolveListAdd(TypeModel model, Type listType, Type itemType, out bool isList)
        {
#if WINRT
            TypeInfo listTypeInfo = listType.GetTypeInfo();
#else
            Type listTypeInfo = listType;
#endif
            isList = model.MapType(ilist).IsAssignableFrom(listTypeInfo);

            Type[]     types = { itemType };
            MethodInfo add   = Helpers.GetInstanceMethod(listTypeInfo, "Add", types);

#if !NO_GENERICS
            if (add == null)
            {   // fallback: look for ICollection<T>'s Add(typedObject) method
                bool forceList = listTypeInfo.IsInterface &&
                                 model.MapType(typeof(System.Collections.Generic.IEnumerable <>)).MakeGenericType(types)
#if WINRT
                                 .GetTypeInfo()
#endif
                                 .IsAssignableFrom(listTypeInfo);

#if WINRT
                TypeInfo constuctedListType = typeof(System.Collections.Generic.ICollection <>).MakeGenericType(types).GetTypeInfo();
#else
                Type constuctedListType = model.MapType(typeof(System.Collections.Generic.ICollection <>)).MakeGenericType(types);
#endif
                if (forceList || constuctedListType.IsAssignableFrom(listTypeInfo))
                {
                    add = Helpers.GetInstanceMethod(constuctedListType, "Add", types);
                }
            }

            if (add == null)
            {
#if WINRT
                foreach (Type tmpType in listTypeInfo.ImplementedInterfaces)
#else
                foreach (Type interfaceType in listTypeInfo.GetInterfaces())
#endif
                {
#if WINRT
                    TypeInfo interfaceType = tmpType.GetTypeInfo();
#endif
                    if (interfaceType.Name == "IProducerConsumerCollection`1" && interfaceType.IsGenericType && interfaceType.GetGenericTypeDefinition().FullName == "System.Collections.Concurrent.IProducerConsumerCollection`1")
                    {
                        add = Helpers.GetInstanceMethod(interfaceType, "TryAdd", types);
                        if (add != null)
                        {
                            break;
                        }
                    }
                }
            }
#endif

            if (add == null)
            {   // fallback: look for a public list.Add(object) method
                types[0] = model.MapType(typeof(object));
                add      = Helpers.GetInstanceMethod(listTypeInfo, "Add", types);
            }
            if (add == null && isList)
            {   // fallback: look for IList's Add(object) method
                add = Helpers.GetInstanceMethod(model.MapType(ilist), "Add", types);
            }
            return(add);
        }
Ejemplo n.º 12
0
        internal static bool IsAssignableFrom(Type target, Type type)
        {
#if WINRT
            return target.GetTypeInfo().IsAssignableFrom(type.GetTypeInfo());
#else
            return target.IsAssignableFrom(type);
#endif
        }