using System; using System.Collections.Generic; namespace Developpez.Dotnet { /// /// Fournit des méthodes d'extension pour les fonctions et actions /// public static partial class FuncExtensions { #region Mise en cache des résultats /// /// Renvoie un wrapper de la fonction qui met en cache le résultat, /// de façon à n'appeler la fonction qu'une seule fois /// /// Le type de retour de la fonction /// La fonction à mettre en cache /// La valeur de retour de la fonction public static Func AsCached(this Func function) { TResult result = default(TResult); bool evaluated = false; object lck = new object(); return () => { lock (lck) { if (!evaluated) { result = function(); evaluated = true; } } return result; }; } /// /// Renvoie un wrapper de la fonction qui met en cache le résultat /// pour chaque valeur de l'argument, de façon à n'appeler la fonction /// qu'une seule fois pour chaque valeur d'argument /// /// Le type du paramètre /// Le type de retour de la fonction /// La fonction à mettre en cache /// La valeur de retour de la fonction public static Func AsCached(this Func function) { var cachedResults = new Dictionary(); return (argument) => { TResult result; lock (cachedResults) { if (!cachedResults.TryGetValue(argument, out result)) { result = function(argument); cachedResults.Add(argument, result); } } return result; }; } #endregion #region Prédicats /// /// Convertit un délégué ]]> en délégué ]]> /// /// Le type du paramètre /// La fonction à convertir /// Un prédicat équivalent à la fonction public static Predicate ToPredicate(this Func function) { return x => function(x); } /// /// Convertit un délégué ]]> en délégué ]]> /// /// Le type du paramètre /// Le prédicat à convertir /// Une fonction équivalente au prédicat public static Func ToFunc(this Predicate predicate) { return x => predicate(x); } /// /// Renvoie la négation d'un prédicat /// /// Le type de paramètre du prédicat /// Le prédicat dont on veut obtenir la négation /// La négation du prédicat public static Func Negate(this Func function) { return x => !function(x); } /// /// Renvoie la négation d'un prédicat /// /// Le type de paramètre du prédicat /// Le prédicat dont on veut obtenir la négation /// La négation du prédicat public static Predicate Negate(this Predicate predicate) { return x => !predicate(x); } #endregion #region Comparaisons /// /// Convertit un délégué ]]> en délégué ]]> /// /// Le type des paramètres /// La fonction à convertir /// Une comparaison équivalente à la fonction public static Comparison ToComparison(this Func function) { return (a, b) => function(a, b); } /// /// Convertit un délégué ]]> en délégué ]]> /// /// Le type des paramètres /// La comparaison à convertir /// Une fonction équivalente à la comparaison public static Func ToFunc(this Comparison comparison) { return (a, b) => comparison(a, b); } #endregion } }