C# 函数式编程:高级技巧与实践

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

C# 函数式编程:进阶篇



函数式编程(FP)是一种近年来积极渗透到 C# 世界的编程范式。借助 .NET 的强大功能,开发者可以将面向对象和函数式方法结合起来,创建更可靠、更易测试且可预测性更强的代码。在本文中,我们将探讨 C# 中的高级 FP 技术,这些技术将帮助您超越简单的 LINQ 使用。



1. 纯函数与副作用:严格控制



纯函数是指其结果仅取决于其输入参数,并且不会产生任何副作用(例如修改全局状态、输入/输出、异常等)的函数。在 C# 中,我们可以通过使用不可变类型并避免修改参数来接近这一理想状态。



// 纯函数:结果仅取决于 x 和 ypublic static int Add(int x, int y) => x + y;

// 非纯函数:依赖于外部状态private static int _counter = 0;public static int IncrementCounter() => ++_counter;


在进阶层面,重要的是将纯计算与具有副作用的操作严格分离。为此,您可以使用 IO 模式(在函数式语言中)或其在 C# 中通过 Func<T> 和惰性求值实现的简化版本。



实用技巧:"惰性执行"



与其立即执行一个带有副作用的操作,不如返回一个将要执行该操作的委托:



public static Func<int> CreateFileReadOperation(string path){    return () => File.ReadAllText(path).Length; // 副作用被延迟}

// 用法var operation = CreateFileReadOperation("data.txt");// ... 纯逻辑 ...int length = operation(); // 在此处执行副作用


2. 函数组合与柯里化



组合是将两个或多个函数合并以创建一个新函数。柯里化是将一个接受多个参数的函数转换为一个接受单个参数的函数链。这些技术使代码更加模块化和可复用。



通过 LINQ 和自定义方法进行组合



在 C# 中,组合可以通过扩展方法来实现:



public static class FuncExtensions{    public static Func<T, TResult> Compose<T, TIntermediate, TResult>(        this Func<T, TIntermediate> first,        Func<TIntermediate, TResult> second)        => x => second(first(x));}

// 示例:f(x) = x + 2, g(x) = x * 3, h = f ∘ gFunc<int, int> addTwo = x => x + 2;Func<int, int> multiplyByThree = x => x * 3;var composed = multiplyByThree.Compose(addTwo); // h(x) = (x*3) + 2Console.WriteLine(composed(5)); // 17


C# 中的柯里化



柯里化允许对函数进行部分应用:



public static Func<int, Func<int, int>> CurriedAdd = x => y => x + y;

var addFive = CurriedAdd(5); // 部分应用Console.WriteLine(addFive(10)); // 15

// 更复杂的示例:带前缀的日志函数public static Func<string, Func<string, string>> CreateLogger = prefix => message => $"[{prefix}] {message}";

var infoLogger = CreateLogger("INFO");Console.WriteLine(infoLogger("System started")); // [INFO] System started


3. Monad 与 Option (Maybe) 的使用



Monad 是一种模式,它允许将函数顺序地应用于包装在上下文中的值(例如,值可能缺失或存在异步性)。在 C# 中,Option<T> 或 Maybe<T> 的实现很流行,用于避免使用 null。



简单的 Option 实现



public class Option<T>{    private readonly T _value;    private readonly bool _hasValue;

pri

博客

书籍推荐