using System; using System.Collections.Generic; using System.Linq.Expressions; using System.Reflection; using Developpez.Dotnet.Properties; namespace Developpez.Dotnet.Linq { /// /// Fournit des méthodes pour travailler avec Linq et les expressions lambda /// public static partial class LinqHelper { /// /// Obtient le nom d'une propriété à partir d'une Expression<Func<T>> /// /// Le type de la propriété à renvoyer (habituellement déterminé par l'inférence de type) /// Une expression qui représente l'accès à une propriété /// Le nom de la propriété accédée par l'expression public static string GetPropertyName(Expression> expression) { return GetProperty(expression).Name; } /// /// Obtient les informations d'une propriété à partir d'une Expression<Func<T>> /// /// Le type de la propriété à renvoyer (habituellement déterminé par l'inférence de type) /// Une expression qui représente l'accès à une propriété /// Les informations de la propriété accédée par l'expression public static PropertyInfo GetProperty(Expression> expression) { var mExpr = expression.Body as MemberExpression; if (mExpr == null) throw new ArgumentException(ExceptionMessages.ExpressionMustBePropertyAccess); return (PropertyInfo)mExpr.Member; } /// /// Obtient le nom d'une méthode à partir d'une Expression<Func<T>> /// /// Le type de retour de la méthode à renvoyer (habituellement déterminé par l'inférence de type) /// Une expression qui représente l'appel à une méthode /// Le nom de la méthode appelée par l'expression public static string GetMethodName(Expression> expression) { return GetMethod(expression).Name; } /// /// Obtient les informations d'une méthode à partir d'une Expression<Func<T>> /// /// Le type de retour de la méthode à renvoyer (habituellement déterminé par l'inférence de type) /// Une expression qui représente l'appel à une méthode /// Les informations de la méthode appelée par l'expression public static MethodInfo GetMethod(Expression> expression) { var callExpr = expression.Body as MethodCallExpression; if (callExpr == null) throw new ArgumentException(ExceptionMessages.ExpressionMustBeMethodCall); return callExpr.Method; } /// /// Obtient le nom d'une méthode à partir d'une Expression<Action> /// /// Une expression qui représente l'appel à une méthode /// Le nom de la méthode appelée par l'expression public static string GetMethodName(Expression expression) { return GetMethod(expression).Name; } /// /// Obtient les informations d'une méthode à partir d'une Expression<Action> /// /// Une expression qui représente l'appel à une méthode /// Les informations de la méthode appelée par l'expression public static MethodInfo GetMethod(Expression expression) { var callExpr = expression.Body as MethodCallExpression; if (callExpr == null) throw new ArgumentException(ExceptionMessages.ExpressionMustBeMethodCall); return callExpr.Method; } /// /// Renvoie l'argument tel quel. Utile pour passer une projection à l'identique à une méthode telle que Select, OrderBy ou GroupBy. /// /// Type de l'argument /// Argument à renvoyer /// L'argument tel quel public static T Identity(T arg) { return arg; } /// /// Génère une séquence en en générant chaque état à partir d'un état /// initial tant que la condition est vérifiée. /// /// Type des états /// Type des résultats /// État initial /// Prédicat qui doit être vérifié pour que l'itération continue /// Fonction qui génère l'état suivant à partir de l'état actuel /// Fonction qui séléctionne un résultat à partir de l'état actuel /// Séquence contenant les résultats générés public static IEnumerable Generate( TState initialState, Func condition, Func iterate, Func resultSelector) { TState state = initialState; while (condition(state)) { yield return resultSelector(state); state = iterate(state); } } #region Expr and Func helpers /// /// Renvoie l'expression passée en paramètre, de façon à profiter de l'inférence de type /// /// Le type de retour de l'expression /// L'expression dont on veut inférer le type /// L'expression passée en paramètre public static Expression> Expr(Expression> expr) { return expr; } /// /// Renvoie l'expression passée en paramètre, de façon à profiter de l'inférence de type /// /// Le type du paramètre de l'expression /// Le type de retour de l'expression /// L'expression dont on veut inférer le type /// L'expression passée en paramètre public static Expression> Expr(Expression> expr) { return expr; } /// /// Renvoie l'expression passée en paramètre, de façon à profiter de l'inférence de type /// /// Le type du paramètre de l'expression /// Le type de retour de l'expression /// Objet utilisé comme modèle pour déterminer le type du paramètre /// L'expression dont on veut inférer le type /// L'expression passée en paramètre public static Expression> Expr(T dummyArg, Expression> expr) { return expr; } /// /// Renvoie la fonction passée en paramètre, de façon à profiter de l'inférence de type /// /// Le type de retour de la fonction /// La fonction dont on veut inférer le type /// La fonction passée en paramètre public static Func Func(Func func) { return func; } /// /// Renvoie la fonction passée en paramètre, de façon à profiter de l'inférence de type /// /// Le type du paramètre de la fonction /// Le type de retour de la fonction /// La fonction dont on veut inférer le type /// La fonction passée en paramètre public static Func Func(Func func) { return func; } /// /// Renvoie la fonction passée en paramètre, de façon à profiter de l'inférence de type /// /// Le type du paramètre de la fonction /// Le type de retour de la fonction /// Objet utilisé comme modèle pour déterminer le type du paramètre /// La fonction dont on veut inférer le type /// La fonction passée en paramètre public static Func Func(T dummyArg, Func func) { return func; } #endregion } }