public static LateBoundMethod Create(MethodInfo method)
        {
            ParameterExpression instanceParameter  = Expression.Parameter(typeof(object), "target");
            ParameterExpression argumentsParameter = Expression.Parameter(typeof(object[]), "arguments");

            MethodCallExpression call = Expression.Call(
                Expression.Convert(instanceParameter, method.DeclaringType),
                method,
                CreateParameterExpressions(method, argumentsParameter));

            Expression <LateBoundMethod> lambda;

            if (method.ReturnType == typeof(void))
            {
                Expression <LateBoundVoidMethod> voidLambda = Expression.Lambda <LateBoundVoidMethod>(
                    Expression.Convert(call, typeof(void)),
                    instanceParameter,
                    argumentsParameter);

                LateBoundVoidMethod compiledVoid = voidLambda.Compile();
                //Inline the method call in a lambda of return til LateBoundMethod
                lambda = (target, arguments) => Invoke(compiledVoid, target, arguments);
            }
            else
            {
                lambda = Expression.Lambda <LateBoundMethod>(
                    Expression.Convert(call, typeof(object)),
                    instanceParameter,
                    argumentsParameter);
            }
            return(lambda.Compile());
        }
Beispiel #2
0
        internal TypeMetaData(Type type)
        {
            FullName = type.FullName;
            IsArray = type.IsArray;
            IsDictionary = type.IsDictionaryType();
            IsCollection = type.HasInterface(typeof (IEnumerable));
            IsQueryable = type.HasInterface(typeof(IQueryable)); 
            IsDeferredLinqQuery = type.IsDeferredLinqQuery();

            IsSet = type.IsSet();

            IsHashtable = type == typeof(Hashtable);

            if (IsArray || IsSet)
            {
                ListType = typeof(List<>).MakeGenericType(type.IsGenericType ? 
                    type.GetGenericArguments().First() :
                    type.GetElementType());//when array

                ListTypeToArrayMethod = ListType.GetMethod("ToArray");
            }

            var enumerableInfo = type.GetEnumerableInfo();
            if (enumerableInfo != null)
            {
                ToArrayMethod = typeof (Enumerable).GetMethod("ToArray").MakeGenericMethod(enumerableInfo.AllEnumerableItemTypes.Last());
                ToListMethod = typeof (Enumerable).GetMethod("ToList").MakeGenericMethod(enumerableInfo.AllEnumerableItemTypes.Last());
                AsQueryableMethod = 
                    (from m in typeof(Queryable).GetMethods()
                     where m.Name == "AsQueryable" && m.IsGenericMethod
                    select m)
                    .First()
                    .MakeGenericMethod(enumerableInfo.AllEnumerableItemTypes.Last());
            }

            if (IsSet)
            {
                ExceptWithMethod = type.GetMethod("ExceptWith").InvokeDelegate<LateBoundVoidMethod>();
            }

           
            ImplementsIList = typeof (IList).IsAssignableFrom(type);

            FieldAccessors = !IsCollection
                                  ? GetAllFields(type)
                                        .Where(t => t.FieldType.IsComplex())
                                        .Select(f => new FieldAccessor(f.Name, f.FieldType, f.ValueGetter(), f.ValueSetter()))
                                        .ToArray()
                                  : new FieldAccessor[] { };
        }
 private static object Invoke(LateBoundVoidMethod m, object target, object[] arguments)
 {
     m.Invoke(target, arguments);
     return(null);
 }
 private static object Invoke(LateBoundVoidMethod m, object target, object[] arguments)
 {
     m.Invoke(target, arguments);
       return null;
 }