internal static MethodInfo FindConversionOperator(MethodInfo[] methods, Type typeFrom, Type typeTo, bool implicitOnly) { foreach (MethodInfo mi in methods) { if (mi.Name != "op_Implicit" && (implicitOnly || mi.Name != "op_Explicit")) { continue; } if (!TypeUtils.AreEquivalent(mi.ReturnType, typeTo)) { continue; } ParameterInfo[] pis = mi.GetParametersCached(); if (!TypeUtils.AreEquivalent(pis[0].ParameterType, typeFrom)) { continue; } return(mi); } return(null); }
internal static MethodInfo GetUserDefinedCoercionMethod(Type convertFrom, Type convertToType, bool implicitOnly) { // check for implicit coercions first Type nnExprType = TypeUtils.GetNonNullableType(convertFrom); Type nnConvType = TypeUtils.GetNonNullableType(convertToType); // try exact match on types MethodInfo[] eMethods = nnExprType.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); MethodInfo method = FindConversionOperator(eMethods, convertFrom, convertToType, implicitOnly); if (method != null) { return(method); } MethodInfo[] cMethods = nnConvType.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); method = FindConversionOperator(cMethods, convertFrom, convertToType, implicitOnly); if (method != null) { return(method); } // try lifted conversion if (!TypeUtils.AreEquivalent(nnExprType, convertFrom) || !TypeUtils.AreEquivalent(nnConvType, convertToType)) { method = FindConversionOperator(eMethods, nnExprType, nnConvType, implicitOnly); if (method == null) { method = FindConversionOperator(cMethods, nnExprType, nnConvType, implicitOnly); } if (method != null) { return(method); } } return(null); }