Esempio n. 1
0
		public static Expression ImplicitTypeParameterConversion (Expression expr, TypeParameterSpec expr_type, TypeSpec target_type)
		{
			//
			// From T to a type parameter U, provided T depends on U
			//
			if (target_type.IsGenericParameter) {
				if (expr_type.TypeArguments != null) {
					foreach (var targ in expr_type.TypeArguments) {
						if (!TypeSpecComparer.Override.IsEqual (target_type, targ))
							continue;

						if (expr == null)
							return EmptyExpression.Null;

						if (expr_type.IsReferenceType && !((TypeParameterSpec)target_type).IsReferenceType)
							return new BoxedCast (expr, target_type);

						return new ClassCast (expr, target_type);
					}
				}

				return null;
			}

			//
			// LAMESPEC: From T to dynamic type because it's like T to object
			//
			if (target_type.BuiltinType == BuiltinTypeSpec.Type.Dynamic) {
				if (expr == null)
					return EmptyExpression.Null;

				if (expr_type.IsReferenceType)
					return new ClassCast (expr, target_type);

				return new BoxedCast (expr, target_type);
			}

			//
			// From T to its effective base class C
			// From T to any base class of C (it cannot contain dynamic or be of dynamic type)
			// From T to any interface implemented by C
			//
			var base_type = expr_type.GetEffectiveBase ();
			if (base_type == target_type || TypeSpec.IsBaseClass (base_type, target_type, false) || base_type.ImplementsInterface (target_type, true)) {
				if (expr == null)
					return EmptyExpression.Null;

				if (expr_type.IsReferenceType)
					return new ClassCast (expr, target_type);

				return new BoxedCast (expr, target_type);
			}

			if (target_type.IsInterface && expr_type.IsConvertibleToInterface (target_type)) {
				if (expr == null)
					return EmptyExpression.Null;

				if (expr_type.IsReferenceType)
					return new ClassCast (expr, target_type);

				return new BoxedCast (expr, target_type);
			}

			return null;
		}
Esempio n. 2
0
		static Expression ExplicitTypeParameterConversionToT (Expression source, TypeSpec source_type, TypeParameterSpec target_type)
		{
			//
			// From the effective base class C of T to T and from any base class of C to T
			//
			var effective = target_type.GetEffectiveBase ();
			if (TypeSpecComparer.IsEqual (effective, source_type) || TypeSpec.IsBaseClass (effective, source_type, false))
				return source == null ? EmptyExpression.Null : new ClassCast (source, target_type);

			return null;
		}