private static int ChooseMorePreciseType(Type type1, Type type2) { if (type1.IsByRef || type2.IsByRef) { if (type1.IsByRef && type2.IsByRef) { type1 = type1.GetElementType(); type2 = type2.GetElementType(); } else if (type1.IsByRef) { type1 = type1.GetElementType(); if (type1 == type2) { return(1); } } else { type2 = type2.GetElementType(); if (type2 == type1) { return(-1); } } } bool c1FromC2, c2FromC1; if (XBaseTypes.IsPrimitive(type1) && XBaseTypes.IsPrimitive(type2)) { c1FromC2 = CanConvertPrimitive(type2, type1); c2FromC1 = CanConvertPrimitive(type1, type2); } else { c1FromC2 = type1.IsAssignableFrom(type2); c2FromC1 = type2.IsAssignableFrom(type1); } if (c1FromC2 == c2FromC1) { return(0); } return(c1FromC2 ? 1 : -1); }
/// <summary> /// Checks if a set of values with given <paramref name="types"/> can be used /// to invoke a method with specified <paramref name="parameters"/>. /// </summary> /// <param name="parameters">Method parameters.</param> /// <param name="types">Argument types.</param> /// <param name="enableParamArray">Try to pack extra arguments into the last parameter when it is marked up with <see cref="ParamArrayAttribute"/>.</param> /// <returns><c>true</c> if method can be called with given arguments, <c>false</c> otherwise.</returns> private static bool FilterParameters(ParameterInfo[] parameters, IList <Type> types, bool enableParamArray) { XValidation.ArgumentNotNull(parameters, nameof(parameters)); XValidation.ArgumentNotNull(types, nameof(types)); if (parameters.Length == 0) { // fast check for parameterless methods return(types.Count == 0); } if (parameters.Length > types.Count) { // not all declared parameters were specified (optional parameters are not supported) return(false); } // check if the last parameter is ParamArray Type paramArrayType = null; if (enableParamArray) { ParameterInfo lastParam = parameters[parameters.Length - 1]; if (lastParam.ParameterType.IsArray && lastParam.IsDefined(typeof(ParamArrayAttribute))) { paramArrayType = lastParam.ParameterType.GetElementType(); } } if (paramArrayType == null && parameters.Length != types.Count) { // when there's no ParamArray, number of parameters should match return(false); } for (int i = 0; i < types.Count; i++) { Type paramType = (paramArrayType != null && i >= parameters.Length - 1) ? paramArrayType : parameters[i].ParameterType; if (paramType == types[i]) { // exact match with provided type continue; } if (paramType == typeof(object)) { // parameter of type object matches anything continue; } if (XBaseTypes.IsPrimitive(paramType)) { if (!XBaseTypes.IsPrimitive(types[i]) || !CanConvertPrimitive(types[i], paramType)) { // primitive parameter can only be assigned from compatible primitive type return(false); } } else { if (!paramType.IsAssignableFrom(types[i])) { return(false); } } } return(true); }
public bool IsPrimitive(Type type) { return(XBaseTypes.IsPrimitive(type)); }