當前位置: 妍妍網 > 碼農

C#中static還能這樣用?

2024-05-10碼農

最近在開發一個微服務計畫,本地使用了 aspire 來構建,在查閱 aspire 文件時,我看到了下面的程式碼片段:

builder.AddRedisOutputCache("cache",static settings => settings.DisableHealthChecks = true);

這裏的 static 關鍵字引起了我的註意, 加 static 和不加 static 到底有什麽區別呢?

點個關註吧👇,我來揭曉答案。

static 關鍵字在 C# 中通常用於類、方法、變量和內容。當它用於類的成員時,這意味著該成員不屬於任何特定的例項,而是屬於類本身。但在 lambda 運算式中,static 的用途則有所不同。

lambda 運算式是一個匿名函式,你可以將它用作方法參數,或者將它賦值給一個變量。在 C# 中,如果一個 lambda 運算式被標記為 static,它就被稱為靜態 lambda 運算式。這意味著它不會捕獲(capture)任何外部的變量,也就是說,它不會參照傳遞給它之外的任何變量 這樣做的好 處是:

  1. 效能最佳化: 由於不捕獲外部變量,靜態 lambda 運算式通常比非靜態 lambda 運算式更高效,因為它們不需要額外的記憶體來儲存對外部變量的參照。

  2. 執行緒安全: 靜態 lambda 運算式不依賴於外部狀態,因此在多執行緒環境中使用時更安全,不會因為外部狀態的改變而產生不可預測的行為。

那麽,如果 lambda 運算式不參照外部變量,是否就意味著加不加 static 都一樣呢?

實際上, 當你聲明一個普通的 lambda 運算式(沒有 static 關鍵字)時,編譯器會生成一個閉包(closure),即使它實際上沒有捕獲任何外部變量。 這個閉包是一個物件,它需要在堆上分配空間,並且可能涉及到額外的記憶體分配和垃圾回收。

另一方面,當你使用 static 關鍵字聲明 lambda 運算式時,編譯器知道這個 lambda 不會捕獲任何外部變量,因此它不需要生成閉包,這意味著它可以在棧上執行,這通常比在堆上分配和管理物件更快

所以,即使在不捕獲外部變量的情況下,使用 static 的 lambda 運算式仍然可能比普通的 lambda 運算式更高效,因為它避免了閉包的建立和相關的記憶體開銷, 同時也允許編譯器進行更多的最佳化。

讓我們來看看兩種寫法的使用場景:

  1. 使用靜態 lambda:當你的 lambda 運算式不需要存取外部變量,或者你想確保它不會因為外部狀態的變化而產生副作用時,使用靜態lambda是一個很好的選擇。

  2. 使用普通 lambda:如果你需要在 lambda 運算式中存取或修改外部變量,那麽你不能使用靜態 lambda 。在這種情況下,普通的 lambda 運算式是必要的。

static 關鍵字在 lambda 運算式中的使用雖然不是必須的, 但在效能敏感的套用或大量使用 lambda 運算式的情況下,static lambda 運算式是一個不錯的 選擇 ,並且能使程式碼更加清晰和安全。下次在寫 lambda 運算式時,不妨考慮一下是否可以使用 static 來最佳化你的程式碼。