diff --git a/GFramework.Core/functional/control/ControlExtensions.cs b/GFramework.Core/functional/control/ControlExtensions.cs
index 90ebc9d..412c9fc 100644
--- a/GFramework.Core/functional/control/ControlExtensions.cs
+++ b/GFramework.Core/functional/control/ControlExtensions.cs
@@ -47,4 +47,179 @@ public static class ControlExtensions
{
return !predicate(value) ? value : null;
}
+
+ ///
+ /// TakeIfValue:值类型版本的 TakeIf,返回 Nullable
+ ///
+ /// 值类型
+ /// 要进行条件判断的输入值
+ /// 条件判断函数
+ /// 条件为真时返回原值,否则返回 null
+ /// 当 predicate 为 null 时抛出
+ ///
+ ///
+ /// var result = 42.TakeIfValue(x => x > 0); // 42
+ /// var result2 = -5.TakeIfValue(x => x > 0); // null
+ ///
+ ///
+ public static TSource? TakeIfValue(
+ this TSource value,
+ Func predicate)
+ where TSource : struct
+ {
+ ArgumentNullException.ThrowIfNull(predicate);
+ return predicate(value) ? value : null;
+ }
+
+ ///
+ /// TakeUnlessValue:值类型版本的 TakeUnless,返回 Nullable
+ ///
+ /// 值类型
+ /// 要进行条件判断的输入值
+ /// 条件判断函数
+ /// 条件为假时返回原值,否则返回 null
+ /// 当 predicate 为 null 时抛出
+ ///
+ /// x < 0); // 42
+ /// var result2 = -5.TakeUnlessValue(x => x < 0); // null
+ /// ]]>
+ ///
+ public static TSource? TakeUnlessValue(
+ this TSource value,
+ Func predicate)
+ where TSource : struct
+ {
+ ArgumentNullException.ThrowIfNull(predicate);
+ return !predicate(value) ? value : null;
+ }
+
+ ///
+ /// When:条件执行,满足条件时执行操作并返回原值
+ ///
+ /// 值的类型
+ /// 输入值
+ /// 条件判断函数
+ /// 满足条件时执行的操作
+ /// 原始值
+ /// 当 predicate 或 action 为 null 时抛出
+ ///
+ ///
+ /// var result = 42
+ /// .When(x => x > 0, x => Console.WriteLine($"Positive: {x}"))
+ /// .When(x => x % 2 == 0, x => Console.WriteLine("Even"));
+ ///
+ ///
+ public static TSource When(
+ this TSource value,
+ Func predicate,
+ Action action)
+ {
+ ArgumentNullException.ThrowIfNull(predicate);
+ ArgumentNullException.ThrowIfNull(action);
+
+ if (predicate(value))
+ action(value);
+
+ return value;
+ }
+
+ ///
+ /// RepeatUntil:重复执行函数直到条件满足
+ ///
+ /// 值的类型
+ /// 初始值
+ /// 每次迭代执行的函数
+ /// 停止条件
+ /// 最大迭代次数(防止无限循环)
+ /// 满足条件时的值
+ /// 当 func 或 predicate 为 null 时抛出
+ /// 当 maxIterations 小于 1 时抛出
+ /// 当达到最大迭代次数仍未满足条件时抛出
+ ///
+ ///
+ /// var result = 1.RepeatUntil(
+ /// x => x * 2,
+ /// x => x >= 100,
+ /// maxIterations: 10
+ /// ); // 128
+ ///
+ ///
+ public static TSource RepeatUntil(
+ this TSource value,
+ Func func,
+ Func predicate,
+ int maxIterations = 1000)
+ {
+ ArgumentNullException.ThrowIfNull(func);
+ ArgumentNullException.ThrowIfNull(predicate);
+ ArgumentOutOfRangeException.ThrowIfLessThan(maxIterations, 1);
+
+ var current = value;
+ var iterations = 0;
+
+ while (!predicate(current))
+ {
+ if (iterations >= maxIterations)
+ throw new InvalidOperationException(
+ $"RepeatUntil 达到最大迭代次数 {maxIterations} 但条件仍未满足");
+
+ current = func(current);
+ iterations++;
+ }
+
+ return current;
+ }
+
+ ///
+ /// Retry:同步重试机制,失败时重试指定次数
+ ///
+ /// 返回值类型
+ /// 要执行的函数
+ /// 最大重试次数
+ /// 每次重试之间的延迟(毫秒)
+ /// 函数执行结果
+ /// 当 func 为 null 时抛出
+ /// 当 maxRetries 小于 0 或 delayMilliseconds 小于 0 时抛出
+ /// 当所有重试都失败时抛出,包含所有异常
+ ///
+ ///
+ /// var result = ControlExtensions.Retry(
+ /// () => UnstableOperation(),
+ /// maxRetries: 3,
+ /// delayMilliseconds: 100
+ /// );
+ ///
+ ///
+ public static TResult Retry(
+ Func func,
+ int maxRetries = 3,
+ int delayMilliseconds = 0)
+ {
+ ArgumentNullException.ThrowIfNull(func);
+ ArgumentOutOfRangeException.ThrowIfNegative(maxRetries);
+ ArgumentOutOfRangeException.ThrowIfNegative(delayMilliseconds);
+
+ var exceptions = new List();
+ var attempts = maxRetries + 1;
+
+ for (var i = 0; i < attempts; i++)
+ {
+ try
+ {
+ return func();
+ }
+ catch (Exception ex)
+ {
+ exceptions.Add(ex);
+
+ if (i < maxRetries && delayMilliseconds > 0)
+ Thread.Sleep(delayMilliseconds);
+ }
+ }
+
+ throw new AggregateException(
+ $"操作在 {attempts} 次尝试后仍然失败",
+ exceptions);
+ }
}
\ No newline at end of file
diff --git a/GFramework.Core/functional/functions/FunctionExtensions.cs b/GFramework.Core/functional/functions/FunctionExtensions.cs
index ce1bd1f..8935946 100644
--- a/GFramework.Core/functional/functions/FunctionExtensions.cs
+++ b/GFramework.Core/functional/functions/FunctionExtensions.cs
@@ -99,4 +99,185 @@ public static class FunctionExtensions
}
#endregion
+
+ #region Compose & AndThen
+
+ ///
+ /// Compose:函数组合,返回 f(g(x))
+ /// 数学表示:(f ∘ g)(x) = f(g(x))
+ ///
+ /// 输入类型
+ /// 中间类型
+ /// 输出类型
+ /// 外层函数
+ /// 内层函数
+ /// 组合后的函数
+ /// 当 f 或 g 为 null 时抛出
+ ///
+ ///
+ /// Func<int, int> addOne = x => x + 1;
+ /// Func<int, int> multiplyTwo = x => x * 2;
+ /// var composed = multiplyTwo.Compose(addOne); // (x + 1) * 2
+ /// var result = composed(5); // (5 + 1) * 2 = 12
+ ///
+ ///
+ public static Func Compose(
+ this Func f,
+ Func g)
+ {
+ ArgumentNullException.ThrowIfNull(f);
+ ArgumentNullException.ThrowIfNull(g);
+ return x => f(g(x));
+ }
+
+ ///
+ /// AndThen:函数链式调用,返回 g(f(x))
+ /// 数学表示:(f >> g)(x) = g(f(x))
+ ///
+ /// 输入类型
+ /// 中间类型
+ /// 输出类型
+ /// 第一个函数
+ /// 第二个函数
+ /// 链式调用后的函数
+ /// 当 f 或 g 为 null 时抛出
+ ///
+ ///
+ /// Func<int, int> addOne = x => x + 1;
+ /// Func<int, int> multiplyTwo = x => x * 2;
+ /// var chained = addOne.AndThen(multiplyTwo); // (x + 1) * 2
+ /// var result = chained(5); // (5 + 1) * 2 = 12
+ ///
+ ///
+ public static Func AndThen(
+ this Func f,
+ Func g)
+ {
+ ArgumentNullException.ThrowIfNull(f);
+ ArgumentNullException.ThrowIfNull(g);
+ return x => g(f(x));
+ }
+
+ #endregion
+
+ #region Curry & Uncurry
+
+ ///
+ /// Curry:将二参数函数柯里化为嵌套的单参数函数
+ ///
+ /// 第一个参数类型
+ /// 第二个参数类型
+ /// 返回值类型
+ /// 要柯里化的函数
+ /// 柯里化后的函数
+ /// 当 func 为 null 时抛出
+ ///
+ ///
+ /// Func<int, int, int> add = (x, y) => x + y;
+ /// var curriedAdd = add.Curry();
+ /// var add5 = curriedAdd(5);
+ /// var result = add5(3); // 8
+ ///
+ ///
+ public static Func> Curry(
+ this Func func)
+ {
+ ArgumentNullException.ThrowIfNull(func);
+ return arg1 => arg2 => func(arg1, arg2);
+ }
+
+ ///
+ /// Curry:将三参数函数柯里化为嵌套的单参数函数
+ ///
+ /// 第一个参数类型
+ /// 第二个参数类型
+ /// 第三个参数类型
+ /// 返回值类型
+ /// 要柯里化的函数
+ /// 柯里化后的函数
+ /// 当 func 为 null 时抛出
+ ///
+ ///
+ /// Func<int, int, int, int> add3 = (x, y, z) => x + y + z;
+ /// var curriedAdd = add3.Curry();
+ /// var result = curriedAdd(1)(2)(3); // 6
+ ///
+ ///
+ public static Func>> Curry(
+ this Func func)
+ {
+ ArgumentNullException.ThrowIfNull(func);
+ return arg1 => arg2 => arg3 => func(arg1, arg2, arg3);
+ }
+
+ ///
+ /// Uncurry:将柯里化的函数还原为多参数函数
+ ///
+ /// 第一个参数类型
+ /// 第二个参数类型
+ /// 返回值类型
+ /// 柯里化的函数
+ /// 还原后的多参数函数
+ /// 当 func 为 null 时抛出
+ ///
+ ///
+ /// Func<int, Func<int, int>> curriedAdd = x => y => x + y;
+ /// var add = curriedAdd.Uncurry();
+ /// var result = add(5, 3); // 8
+ ///
+ ///
+ public static Func Uncurry(
+ this Func> func)
+ {
+ ArgumentNullException.ThrowIfNull(func);
+ return (arg1, arg2) => func(arg1)(arg2);
+ }
+
+ #endregion
+
+ #region Defer & Once
+
+ ///
+ /// Defer:延迟执行函数,返回 Lazy<T>
+ ///
+ /// 返回值类型
+ /// 要延迟执行的函数
+ /// 包装了延迟执行的 Lazy 对象
+ /// 当 func 为 null 时抛出
+ ///
+ ///
+ /// var lazy = (() => ExpensiveComputation()).Defer();
+ /// // 此时尚未执行
+ /// var result = lazy.Value; // 首次访问时才执行
+ ///
+ ///
+ public static Lazy Defer(this Func func)
+ {
+ ArgumentNullException.ThrowIfNull(func);
+ return new Lazy(func);
+ }
+
+ ///
+ /// Once:确保函数只执行一次,后续调用返回缓存的结果(线程安全)
+ ///
+ /// 返回值类型
+ /// 要执行的函数
+ /// 包装后的函数,确保只执行一次
+ /// 当 func 为 null 时抛出
+ ///
+ ///
+ /// var counter = 0;
+ /// var once = (() => ++counter).Once();
+ /// var result1 = once(); // 1
+ /// var result2 = once(); // 1 (不会再次执行)
+ ///
+ ///
+ public static Func Once(this Func func)
+ {
+ ArgumentNullException.ThrowIfNull(func);
+ var lazy = new Lazy(func, LazyThreadSafetyMode.ExecutionAndPublication);
+ return () => lazy.Value;
+ }
+
+ #endregion
}
\ No newline at end of file
diff --git a/GFramework.Core/functional/pipe/PipeExtensions.cs b/GFramework.Core/functional/pipe/PipeExtensions.cs
index 420ab54..d2e46c2 100644
--- a/GFramework.Core/functional/pipe/PipeExtensions.cs
+++ b/GFramework.Core/functional/pipe/PipeExtensions.cs
@@ -30,4 +30,116 @@ public static class PipeExtensions
action(value);
return value;
}
+
+ ///
+ /// Tap:
+ /// Also 的别名,对值执行副作用操作并返回原值
+ /// 提供更符合某些编程风格的命名
+ ///
+ /// 值的类型
+ /// 要处理的值
+ /// 要执行的副作用操作
+ /// 原始值
+ /// 当 action 为 null 时抛出
+ ///
+ ///
+ /// var result = GetUser()
+ /// .Tap(user => Console.WriteLine($"User: {user.Name}"))
+ /// .Tap(user => _logger.LogInfo($"Processing user {user.Id}"));
+ ///
+ ///
+ public static T Tap(this T value, Action action)
+ {
+ ArgumentNullException.ThrowIfNull(action);
+ action(value);
+ return value;
+ }
+
+ ///
+ /// Pipe:
+ /// 管道操作符,将值传递给函数并返回结果
+ /// 用于构建流式的函数调用链
+ ///
+ /// 输入类型
+ /// 输出类型
+ /// 输入值
+ /// 转换函数
+ /// 转换后的值
+ /// 当 func 为 null 时抛出
+ ///
+ ///
+ /// var result = 42
+ /// .Pipe(x => x * 2)
+ /// .Pipe(x => x.ToString())
+ /// .Pipe(s => $"Result: {s}");
+ ///
+ ///
+ public static TResult Pipe(
+ this TSource value,
+ Func func)
+ {
+ ArgumentNullException.ThrowIfNull(func);
+ return func(value);
+ }
+
+ ///
+ /// Let:
+ /// 作用域函数,将值传递给函数并返回结果
+ /// 与 Pipe 功能相同,但提供不同的语义(Kotlin 风格)
+ ///
+ /// 输入类型
+ /// 输出类型
+ /// 输入值
+ /// 转换函数
+ /// 转换后的值
+ /// 当 transform 为 null 时抛出
+ ///
+ ///
+ /// var result = GetUser().Let(user => new UserDto
+ /// {
+ /// Id = user.Id,
+ /// Name = user.Name
+ /// });
+ ///
+ ///
+ public static TResult Let(
+ this TSource value,
+ Func transform)
+ {
+ ArgumentNullException.ThrowIfNull(transform);
+ return transform(value);
+ }
+
+ ///
+ /// PipeIf:
+ /// 条件管道,根据条件选择不同的转换函数
+ ///
+ /// 输入类型
+ /// 输出类型
+ /// 输入值
+ /// 条件判断函数
+ /// 条件为真时的转换函数
+ /// 条件为假时的转换函数
+ /// 转换后的值
+ /// 当任何参数为 null 时抛出
+ ///
+ ///
+ /// var result = 42.PipeIf(
+ /// x => x > 0,
+ /// x => $"Positive: {x}",
+ /// x => $"Non-positive: {x}"
+ /// );
+ ///
+ ///
+ public static TResult PipeIf(
+ this TSource value,
+ Func predicate,
+ Func ifTrue,
+ Func ifFalse)
+ {
+ ArgumentNullException.ThrowIfNull(predicate);
+ ArgumentNullException.ThrowIfNull(ifTrue);
+ ArgumentNullException.ThrowIfNull(ifFalse);
+ return predicate(value) ? ifTrue(value) : ifFalse(value);
+ }
}
\ No newline at end of file