Binder to select the appropriate method for implicit conversion.
Inheritance: System.Reflection.Binder
        public void TestBinder()
        {
            Binder binder = new ImplicitMethodBinder(typeof (Class01), typeof (Class02));
            MethodInfo methodInfo = typeof (Class01).GetMethod(METHOD, BindingFlags.Public | BindingFlags.Static, binder, new[] {typeof (Class01)}, null);
            Assert.Null(methodInfo, METHOD_MUST_NOT_EXIST);

            methodInfo = typeof (Class01).GetMethod(METHOD, BindingFlags.Public | BindingFlags.Static, binder, new[] {typeof (Class02)}, null);
            Assert.Null(methodInfo, METHOD_MUST_NOT_EXIST);

            methodInfo = typeof (Class02).GetMethod(METHOD, BindingFlags.Public | BindingFlags.Static, binder, new[] {typeof (Class01)}, null);
            Assert.NotNull(methodInfo, METHOD_MUST_EXIST);

            methodInfo = typeof (Class02).GetMethod(METHOD, BindingFlags.Public | BindingFlags.Static, binder, new[] {typeof (Class02)}, null);
            Assert.NotNull(methodInfo, METHOD_MUST_EXIST);
        }
Example #2
0
		/// <summary>
		///   Gets the converter between the source and destination type.
		/// </summary>
		internal static MethodInfo GetConverter (Type sourceType, Type targetType)
		{
			// Dereference enumerations
			if (sourceType.IsEnum) {
				sourceType = Enum.GetUnderlyingType (sourceType);
			}
			if (targetType.IsEnum) {
				targetType = Enum.GetUnderlyingType (targetType);
			}

			// If the types are equivalent, return
			if (sourceType == targetType) {
				return null;
			}

			// Process well-known conversion first);
			if (sourceType == typeof(int) && targetType == typeof(long)) {
				return INT_2_LONG;
			}
			if (sourceType == typeof(long) && targetType == typeof(int)) {
				return LONG_2_INT;
			}

			if (sourceType == typeof(uint) && targetType == typeof(ulong)) {
				return UINT_2_ULONG;
			}
			if (sourceType == typeof(ulong) && targetType == typeof(uint)) {
				return ULONG_2_UINT;
			}

			if (sourceType == typeof(float) && targetType == typeof(int)) {
				return FLOAT_2_INT;
			}
			if (sourceType == typeof(int) && targetType == typeof(float)) {
				return INT_2_FLOAT;
			}

			if (sourceType == typeof(float) && targetType == typeof(uint)) {
				return FLOAT_2_UINT;
			}
			if (sourceType == typeof(uint) && targetType == typeof(float)) {
				return UINT_2_FLOAT;
			}

			if (sourceType == typeof(float) && targetType == typeof(long)) {
				return FLOAT_2_LONG;
			}
			if (sourceType == typeof(long) && targetType == typeof(float)) {
				return LONG_2_FLOAT;
			}

			if (sourceType == typeof(float) && targetType == typeof(ulong)) {
				return FLOAT_2_ULONG;
			}
			if (sourceType == typeof(ulong) && targetType == typeof(float)) {
				return ULONG_2_FLOAT;
			}

			if (sourceType == typeof(float) && targetType == typeof(double)) {
				return FLOAT_2_DOUBLE;
			}
			if (sourceType == typeof(double) && targetType == typeof(float)) {
				return DOUBLE_2_FLOAT;
			}

			// Process value-type conversion
			if (sourceType.IsValueType && targetType.IsValueType) {
				Binder binder = new ImplicitMethodBinder (sourceType, targetType);
				MethodInfo converter = sourceType.GetMethod ("op_Implicit", BindingFlags.Public | BindingFlags.Static, binder, new[] {sourceType}, null) ??
					targetType.GetMethod ("op_Implicit", BindingFlags.Public | BindingFlags.Static, binder, new[] {sourceType}, null);
				if (converter != null) {
					return converter;
				}
			}

			throw new NotSupportedException (String.Format (Resources.CannotFindAConverter, sourceType, targetType));
		}
Example #3
0
		public static void CastValueType (ILGenerator generator, Type sourceType, Type targetType)
		{
			if (sourceType.Equals (targetType)) {
				return;
			}
			
			if (sourceType.IsEnum) {
				Type baseType = Enum.GetUnderlyingType (sourceType);
				if (!baseType.Equals (targetType)) {
					if (targetType == typeof(long) && baseType == typeof(int)) {
						generator.Emit (OpCodes.Conv_I8);
					} else if (targetType == typeof(ulong) && baseType == typeof(uint)) {
						generator.Emit (OpCodes.Conv_U8);
					} else {
						throw new NotSupportedException ("1. Cannot cast from " + sourceType + " to " + targetType);
					}
				}
			} else if (targetType.IsEnum) {
				Type baseType = Enum.GetUnderlyingType (targetType);
				if (!baseType.Equals (sourceType)) {
					if (sourceType == typeof(long) && baseType == typeof(int)) {
						generator.Emit (OpCodes.Conv_I4);
					} else if (sourceType == typeof(ulong) && baseType == typeof(uint)) {
						generator.Emit (OpCodes.Conv_U4);
					} else {
						throw new NotSupportedException ("2. Cannot cast from " + sourceType + " to " + targetType);
					}
				}
			} else {
				Binder binder = new ImplicitMethodBinder (sourceType, targetType);
				MethodInfo converter = sourceType.GetMethod ("op_Implicit", BindingFlags.Public | BindingFlags.Static, binder, new[] {sourceType}, null) ??
					targetType.GetMethod ("op_Implicit", BindingFlags.Public | BindingFlags.Static, binder, new[] {sourceType}, null);
				if (converter != null) {
					generator.Emit (OpCodes.Call, converter);
				} else {
					throw new NotSupportedException ("3. Cannot cast from " + sourceType + " to " + targetType);
				}
			}
		}