public static bool InEnumerable(object arg, IEnumerable set) { Require.NotNull(set, "set"); var dictionary = set as IDictionary; if (dictionary != null) { return(dictionary.Contains(arg)); } Type argType = null; if (arg != null) { argType = arg.GetType(); } foreach (var item in set) { if (arg == null) { if (item == null) { return(true); } } else if (item != null) { var targetType = item.GetType(); if (argType != targetType) { if (TypeUtil.CanCastImplicitely(argType, targetType, false)) { if (Equals(TypeUtil.CastImplicitely(arg, targetType), item)) { return(true); } } else if (TypeUtil.CanCastImplicitely(targetType, argType, false)) { if (Equals(arg, TypeUtil.CastImplicitely(item, argType))) { return(true); } } } else { if (Equals(arg, item)) { return(true); } } } } return(false); }
private void TestArgumentType(Type parameterType, Type argumentType, bool argumentNull, ref bool match, ref bool implicitMatch) { if ( !parameterType.IsValueType && argumentNull ) { return; } if (parameterType != argumentType) { match = false; } if (!TypeUtil.CanCastImplicitely( argumentType, parameterType, argumentNull )) { implicitMatch = false; } }
public override IExpression Cast(Cast cast) { if (cast.CastType == CastType.Convert) { var constant = cast.Operand as Constant; if (TypeUtil.CanCastImplicitely( cast.Operand.Type, cast.Type, constant != null && constant.Value == null )) { return(new Cast(cast.Operand, cast.Type)); } string methodName = null; switch (Type.GetTypeCode(cast.Type)) { case TypeCode.Boolean: methodName = "ToBoolean"; break; case TypeCode.Byte: methodName = "ToByte"; break; case TypeCode.Char: methodName = "ToChar"; break; case TypeCode.DateTime: methodName = "ToDate"; break; case TypeCode.Decimal: methodName = "ToDecimal"; break; case TypeCode.Double: methodName = "ToDouble"; break; case TypeCode.Int32: methodName = "ToInteger"; break; case TypeCode.Int64: methodName = "ToLong"; break; case TypeCode.SByte: methodName = "ToSByte"; break; case TypeCode.Int16: methodName = "ToShort"; break; case TypeCode.Single: methodName = "ToSingle"; break; case TypeCode.String: methodName = "ToString"; break; case TypeCode.UInt32: methodName = "ToUInteger"; break; case TypeCode.UInt64: methodName = "ToULong"; break; case TypeCode.UInt16: methodName = "ToUShort"; break; } if (methodName != null) { var method = _resolver.FindOperatorMethod( methodName, Array.Empty <Type>(), null, new[] { cast.Operand.Type } ); Debug.Assert(method != null && method.ReturnType == cast.Type); return(new MethodCall( new TypeAccess(method.DeclaringType), method, new[] { cast.Operand } )); } else { return(new Cast(cast.Operand, cast.Type)); } } return(base.Cast(cast)); }
public void MethodCall(MethodCall methodCall) { bool isStatic = methodCall.Operand is TypeAccess; if (!isStatic) { bool emitBox = false; bool emitStoreLoad = false; if ( (methodCall.Operand is FieldAccess || methodCall.Operand is Constant) && methodCall.Operand.Type.IsValueType && !methodCall.MethodInfo.DeclaringType.IsValueType ) { emitBox = true; } else if ( methodCall.Operand.Type.IsValueType && ( !(methodCall.Operand is FieldAccess) || methodCall.MethodInfo.DeclaringType.IsValueType ) ) { emitStoreLoad = true; } // Signal field access that we're using the field as a // parameter. _fieldAsParameter = methodCall.Operand is FieldAccess && methodCall.MethodInfo.DeclaringType.IsValueType && !emitStoreLoad; try { methodCall.Operand.Accept(this); } finally { _fieldAsParameter = false; } if (emitBox) { _il.Emit(OpCodes.Box, methodCall.Operand.Type); } else if (emitStoreLoad) { Debug.Assert(methodCall.Operand.Type == methodCall.MethodInfo.DeclaringType); var builder = _il.DeclareLocal(methodCall.Operand.Type); _il.Emit(OpCodes.Stloc, builder); _il.Emit(OpCodes.Ldloca, builder); } } var parameters = methodCall.MethodInfo.GetParameters(); var arguments = methodCall.Arguments; bool paramsMethod = parameters.Length > 0 && parameters[parameters.Length - 1].GetCustomAttributes(typeof(ParamArrayAttribute), true).Length == 1; int mandatoryParameterCount = paramsMethod ? parameters.Length - 1 : parameters.Length; for (int i = 0; i < mandatoryParameterCount; i++) { Emit(arguments[i], parameters[i].ParameterType); } if (paramsMethod) { var paramsType = parameters[parameters.Length - 1].ParameterType; var elementType = paramsType.GetElementType(); bool emitted = false; // When the params argument is missing, a new array is issued. if (arguments.Count == mandatoryParameterCount) { ILUtil.EmitEmptyArray(_il, elementType); emitted = true; } else if (arguments.Count == mandatoryParameterCount + 1) { var lastArgument = arguments[arguments.Count - 1]; // Null arguments are passed blindly. if (lastArgument is Constant constant && constant.Value == null) { ILUtil.EmitNull(_il); emitted = true; } else { // So are array arguments that can be casted. if ( lastArgument.Type.IsArray && TypeUtil.CanCastImplicitely(lastArgument.Type, paramsType, false) ) { Emit(lastArgument, paramsType); emitted = true; } } } // If we didn't find a shortcut, emit the array with all // arguments. if (!emitted) { ILUtil.EmitArray( _il, elementType, arguments.Count - mandatoryParameterCount, p => Emit(arguments[mandatoryParameterCount + p], elementType) ); } }
internal MethodInfo FindOperatorMethod(string methodName, Type[] sourceTypes, Type returnType, Type[] parameterTypes, bool[] parametersNull) { var candidates = new List <MethodInfo>(); foreach (var sourceType in sourceTypes) { foreach (var method in sourceType.GetMethods(BindingFlags.Static | BindingFlags.Public)) { if (method.Name != methodName) { continue; } var parameters = method.GetParameters(); if (parameters.Length != parameterTypes.Length) { continue; } bool match = true; bool implicitMatch = true; if (returnType != null) { match = returnType == method.ReturnType; implicitMatch = TypeUtil.CanCastImplicitely( method.ReturnType, returnType, false ); } for (int i = 0; i < parameterTypes.Length; i++) { if (parameters[i].ParameterType != parameterTypes[i]) { match = false; } if (!TypeUtil.CanCastImplicitely( parameterTypes[i], parameters[i].ParameterType, parametersNull != null && parametersNull[i] )) { implicitMatch = false; } } if (match) { return(method); } if (implicitMatch) { candidates.Add(method); } } } return(candidates.Count == 1 ? candidates[0] : null); }