Chapter 4 - Item 40 : Distinguish Early from Deferred Execution

Effective C# (Covers C# 6.0), (includes Content Update Program): 50 Specific Ways to Improve Your C#, 3rd Edition By Bill Wagner 讀後心得

前幾節已介紹過立即執行與延遲執行的差異,本節進一步比較在設計程式時,需注意兩者差異的地方。

假設已有定義下列方法:

public int Method1( ) => 5;

public int Method2( ) => 10;

public int Method3( ) => 15;

首先是立即執行。

public int DoStuff( int f1, int f2, int f3 )
    => f1 * f2 * f3;

var answer = DoStuff( Method1( ), Method2( ), Method3( ) );

程式碼執行順序為:
1. 呼叫 Method1( ) 以產生 DoStuff 第一個參數。
2. 呼叫 Method2( ) 以產生 DoStuff 第二個參數。
3. 呼叫 Method3( ) 以產生 DoStuff 第三個參數。
4. 呼叫 DoStuff 並帶入以上產生的參數。

再來是延遲執行。

public int DoStuff2( Func<int> f1, Func<int> f2, Func<int> f3 )
    => f1( ) * f2( ) * f3( );

var answer2 = DoStuff2( ( ) => Method1( ),
    ( ) => Method2( ),
    ( ) => Method3( ) );

程式碼執行順序為:
1. 呼叫 DoStuff2,傳入 lambda 委派。
2. 依照在 DoStuff2 中的邏輯呼叫各委派(也有可能不呼叫)。
3. 各委派執行的順序與時間點由 DoStuff2 的實作內容決定。

最後,也可以混合的使用兩者。

var cache = Method1( );

var answer3 = DoStuff2( ( ) => cache,
    ( ) => Method2( ),
    ( ) => Method3( ) );

cache 變數儲存了 Method1 當下的執行結果,在 DoStuff2 呼叫該委派時,將回傳 cache;相當於立即執行的效果。

結論:
1. 依照實際情況運用立即執行與延遲執行的特性。

2. 遇到混合情境,可利用預先快取的方式,儲存需要立即執行的變數。