Exemple #1
0
        public static Task <TRes> Transform <TArg, TRes>(this Task <TArg> task, Func <TArg, TRes> transformer)
        {
            if (transformer == null)
            {
                ExThrowers.ThrowArgNull(nameof(transformer));
            }
            var tcs = new TaskCompletionSource <TRes>();

            task.ContinueWith(t =>
            {
                if (t.IsFaulted)
                {
                    tcs.SetException(t.Exception);
                }
                else if (t.IsCanceled)
                {
                    tcs.SetCanceled();
                }
                else
                {
                    try
                    {
                        tcs.SetResult(transformer(t.Result));
                    }
                    catch (Exception ex)
                    {
                        tcs.SetException(ex);
                    }
                }
            }, TaskContinuationOptions.ExecuteSynchronously);
            return(tcs.Task);
        }
Exemple #2
0
        public static T CreateCustomDelegate <T>(this MethodInfo m, params Type[] genericArgs) where T : class
        {
            var delType = typeof(T);

            if (!typeof(Delegate).IsAssignableFrom(delType))
            {
                ExThrowers.ThrowArgEx("T is not Delegate type");
            }
            if (genericArgs == null)
            {
                ExThrowers.ThrowArgNull(nameof(genericArgs));
            }
            var delInvokeM = delType.GetMethod("Invoke");
            var delParams  = delInvokeM.GetParameters();
            var parentType = m.DeclaringType;
            var retType    = m.ReturnType;
            var args       = m.GetParameters().Select(p => p.ParameterType).ToArray();

            if (delParams.Length != (args.Length + (m.IsStatic ? 0 : 1)))
            {
                ExThrowers.ThrowArgEx("Number of Delegate arguments does not match method");
            }

            var argsParams = delParams.Select(p => Expression.Parameter(p.ParameterType, p.Name)).ToArray();

            var callParams = m.IsStatic ? argsParams : argsParams.Skip(1);
            var callArgs   = callParams.Select((arg, i) =>
            {
                if (arg.Type == args[i])
                {
                    return((Expression)arg);
                }
                return(Expression.Convert(arg, args[i]));
            });

            var callInstParam = m.IsStatic ? null :
                                ((parentType == typeof(object)) ? (Expression)argsParams[0] : Expression.Convert(argsParams[0], parentType));

            Expression call = m.IsStatic ? Expression.Call(m.DeclaringType, m.Name, genericArgs, callArgs.ToArray()) :
                              Expression.Call(callInstParam, m.Name, genericArgs, callArgs.ToArray());

            if (retType == typeof(void))
            {
                if (delInvokeM.ReturnType != typeof(void))
                {
                    call = Expression.Block(call, Expression.Default(delInvokeM.ReturnType)); // Return default(ReturnType)
                }
            }
            else if (retType != delInvokeM.ReturnType)
            {
                if (delInvokeM.ReturnType != typeof(void) && (retType.IsValueType || delInvokeM.ReturnType.IsValueType))
                {
                    call = Expression.Convert(call, delInvokeM.ReturnType);
                }
            }
            var expr = Expression.Lambda(delType, call, argsParams);

            return(expr.Compile() as T);
        }
Exemple #3
0
 public static bool TryGetValueTupleTypes(this Type type, out Type[] types)
 {
     if (type == null)
     {
         ExThrowers.ThrowArgNull(nameof(type));
     }
     types = null;
     if (!type.FullName.StartsWith("System.ValueTuple`", StringComparison.Ordinal))
     {
         return(false);
     }
     types = type.GetGenericArguments();
     return(true);
 }
Exemple #4
0
        public static MethodInvoker DelegateForMethod(this MethodInfo m, params Type[] genericArgs)
        {
            if (genericArgs == null)
            {
                ExThrowers.ThrowArgNull(nameof(genericArgs));
            }
            var parentType = m.DeclaringType;
            var retType    = m.ReturnType;
            var args       = m.GetParameters().Select(p => p.ParameterType).ToArray();

            var instParam = Expression.Parameter(typeof(object), "instance");
            var argsParam = Expression.Parameter(typeof(object[]), "args");

            var indexedParams = args.Select((arg, i) =>
            {
                Expression argExpr = Expression.ArrayAccess(argsParam, Expression.Constant(i));
                if (arg == typeof(object))
                {
                    return(argExpr);
                }
                return(Expression.Convert(argExpr, arg));
            }).ToArray();

            Expression call = m.IsStatic ? Expression.Call(m.DeclaringType, m.Name, genericArgs, indexedParams) :
                              Expression.Call((parentType == typeof(object)) ? (Expression)instParam : Expression.Convert(instParam, parentType), m.Name, genericArgs, indexedParams);

            Expression <Action <object[]> > callArgEx = a => ExThrowers.ThrowArgEx($"Number of supplied arguments ({a.Length}) does not match number of method arguments ({args.Length})");
            var checkerExpr = Expression.IfThen(Expression.NotEqual(Expression.ArrayLength(argsParam), Expression.Constant(args.Length)),
                                                Expression.Invoke(callArgEx, argsParam));

            var checkedCall = Expression.Block(checkerExpr, call);

            if (retType == typeof(void))
            {
                call = Expression.Block(checkedCall, Expression.Constant(null, typeof(object))); // Return null
            }
            else if (retType.IsValueType)
            {
                call = Expression.Convert(checkedCall, typeof(object)); // Box
            }
            else
            {
                call = checkedCall;
            }

            var expr = Expression.Lambda(typeof(MethodInvoker), call, instParam, argsParam);

            return((MethodInvoker)expr.Compile());
        }
Exemple #5
0
        public static Func <object> GetParameterlessConstructor(this Type type)
        {
            if (type == null)
            {
                ExThrowers.ThrowArgNull(nameof(type));
            }

            Expression call = Expression.New(type);

            if (type.IsValueType)
            {
                call = Expression.Convert(call, typeof(object));
            }

            var expr = Expression.Lambda(typeof(Func <object>), call);

            return((Func <object>)expr.Compile());
        }
        public static bool TryGetValueTupleTypes(this ParameterInfo pi, out TupleArg[] args)
        {
            if (pi == null)
            {
                ExThrowers.ThrowArgNull(nameof(pi));
            }
            args = null;
            var paramType = pi.ParameterType;

            if (!paramType.FullName.StartsWith("System.ValueTuple`", StringComparison.Ordinal))
            {
                return(false);
            }
            var attr   = pi.GetCustomAttribute <TupleElementNamesAttribute>();
            int offset = 0;

            args = PopulateTupleArgs(paramType, attr?.TransformNames, ref offset);
            return(true);
        }