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
}
}