最近在开发一个微服务项目,本地使用了 aspire 来构建,在查阅 aspire 文档时,我看到了下面的代码片段:
builder.AddRedisOutputCache(
"cache",
static settings => settings.DisableHealthChecks = true);
这里的 static 关键字引起了我的注意, 加 static 和不加 static 到底有什么区别呢?
点个关注吧👇,我来揭晓答案。
static 关键字在 C# 中通常用于类、方法、变量和属性。当它用于类的成员时,这意味着该成员不属于任何特定的实例,而是属于类本身。但在 lambda 表达式中,static 的用途则有所不同。
lambda 表达式是一个匿名函数,你可以将它用作方法参数,或者将它赋值给一个变量。在 C# 中,如果一个 lambda 表达式被标记为 static,它就被称为静态 lambda 表达式。这意味着它不会捕获(capture)任何外部的变量,也就是说,它不会引用传递给它之外的任何变量 。 这样做的好 处是:
性能优化: 由于不捕获外部变量,静态 lambda 表达式通常比非静态 lambda 表达式更高效,因为它们不需要额外的内存来存储对外部变量的引用。
线程安全: 静态 lambda 表达式不依赖于外部状态,因此在多线程环境中使用时更安全,不会因为外部状态的改变而产生不可预测的行为。
那么,如果 lambda 表达式不引用外部变量,是否就意味着加不加 static 都一样呢?
实际上, 当你声明一个普通的 lambda 表达式(没有 static 关键字)时,编译器会生成一个闭包(closure),即使它实际上没有捕获任何外部变量。 这个闭包是一个对象,它需要在堆上分配空间,并且可能涉及到额外的内存分配和垃圾回收。
另一方面,当你使用 static 关键字声明 lambda 表达式时,编译器知道这个 lambda 不会捕获任何外部变量,因此它不需要生成闭包,这意味着它可以在栈上执行,这通常比在堆上分配和管理对象更快 。
所以,即使在不捕获外部变量的情况下,使用 static 的 lambda 表达式仍然可能比普通的 lambda 表达式更高效,因为它避免了闭包的创建和相关的内存开销, 同时也允许编译器进行更多的优化。
让我们来看看两种写法的使用场景:
使用静态 lambda:当你的 lambda 表达式不需要访问外部变量,或者你想确保它不会因为外部状态的变化而产生副作用时,使用静态lambda是一个很好的选择。
使用普通 lambda:如果你需要在 lambda 表达式中访问或修改外部变量,那么你不能使用静态 lambda 。在这种情况下,普通的 lambda 表达式是必要的。
static 关键字在 lambda 表达式中的使用虽然不是必须的, 但在性能敏感的应用或大量使用 lambda 表达式的情况下,static lambda 表达式是一个不错的 选择 ,并且能使代码更加清晰和安全。下次在写 lambda 表达式时,不妨考虑一下是否可以使用 static 来优化你的代码。