委托 Lambda表達式 LINQ 技術演變


最近回顧了下基礎知識,看了金旭亮老師的一些視頻,通過一個代碼的重構演示了LINQ由來,也對委托,lambda表達式有了新的認識,在此做一筆記,也和大家交流。

1,先使用一個簡單的例子,查找輸出奇數的功能

static void FindOddNumbers()
{
    var nums = new int[] {0,1,2,3,4,5,6,7,8,9};
    var result = new List<int>();
    foreach (var item in nums)
    {
        if (num%2 !=0)
        {
            result.Add(item);
        }
    }
    foreach (var item in result)
    {
        Console.WriteLine(item);
    }
}

2,將判斷提取為一個方法

static bool IsOdd(int num)
{
    return num%2 !=0;
}

然后查找方法就可以修改為

static void FindOddNumbers()
{
    var nums = new int[] {0,1,2,3,4,5,6,7,8,9};
    var result = new List<int>();
    foreach (var item in nums)
    {
        if (IsOdd(item))
        {
            result.Add(item);
        }
    }
    foreach (var item in result)
    {
        Console.WriteLine(item);
    }
}
View Code

 3,將數據處理功能獨立成一個方法

static IEnumerable<int> FilterIntegers(IEnumerable<int> List)
{
    var result = new List<int>();
    foreach (var item in List)
    {
        if (IsOdd(item))
        {
            result.Add(item);
        }
    }
    return result;
}

代碼修改為,數據處理,數據顯示功能就分開了

static void FindOddNumbers()
{
    var nums = new int[] {0,1,2,3,4,5,6,7,8,9};
    var result = FilterIntegers(nums);
    
    foreach (var item in result)
    {
        Console.WriteLine(item);
    }
}
View Code

4,引入委托,允許外部臨時的指定條件,選擇奇數還是偶數

//增加偶數判斷方法
static bool IsEven(int num)
{
    return num%2 == 0;
}

//定義一個 返回值為bool類型的委托
private delegate bool PredicateDelegate(int value);

//過濾整數 這個函數,增加一個委托參數
static IEnumerable<int> FilterIntegers(IEnumerable<int> List, PredicateDelegate predicate)
{
    var result = new List<int>();
    foreach (var item in List)
    {
        if (predicate(item))
        {
            result.Add(item);
        }
    }
    return result;
}

//修改查找奇數 現在過濾就比較靈活,就可以傳入Isodd,IsEven來過濾奇數還是偶數
static void FindOddNumbers()
{
    var nums = new int[] {0,1,2,3,4,5,6,7,8,9};
    var result = FilterIntegers(nums,IsOdd);
    //result = FilterIntegers(nums,IsEven); 
    foreach (var item in result)
    {
        Console.WriteLine(item);
    }
}

//這里也可初始化一個委托,然后傳入一個委托

 PredicateDelegate myDelegate = IsOdd;
 var result = FilterIntegers(nums, myDelegate);
 
//委托也可以這樣,用一個匿名函數來初始化
PredicateDelegate myDelegate = delegate(int num)
{
    return num%2 != 0;
};
//用lambda表達式,就能簡化這一部分代碼
PredicateDelegate myDelegate = num => { return num % 2 != 0; };
//進一步簡化
PredicateDelegate myDelegate = num => num % 2 != 0; 

用lambda表達式兩種基本格式
  1,(input parameters)=>表達式
  2,(input parameters)=>{語句;}
只有一個輸入參數時,()可以省略;
方法主體只有一條return語句時,return 關鍵字也可以省略

那么就可以刪除委托,直接傳遞一個lambda表達式

var result = FilterIntegers(nums, num => num % 2 != 0);

 

5,引入泛型委托,使方法不單依賴於整形

//定義一個泛型的委托
private delegate bool PredicateGenericDelegate<T>(T value);
//修改過濾整形方法, 現在這個方法不單依賴整形
static IEnumerable<T> Filter<T>(IEnumerable<T> List
        , PredicateGenericDelegate<T> predicate)
{
    var result = new List<T>();
    foreach (var item in List)
    {
        if (predicate(item))
        {
            result.Add(item);
        }
    }
    return result;
}

6,使用系統定義的泛型委托Func<T> ,簡化代碼

//刪除泛型委托的定義,代碼修改為
static IEnumerable<T> Filter<T>(IEnumerable<T> List
    , Func<T,bool> predicate)
{
    var result = new List<T>();
    foreach (var item in List)
    {
        if (predicate(item))
        {
            result.Add(item);
        }
    }
    return result;
}
//---------------------------------------------------------------------------------------------------
//使用lambda表達式
//刪除IsOdd,IsEven 這兩個函數 ,代碼修改為
static void FindOddNumbers()
{
    var nums = new int[] {0,1,2,3,4,5,6,7,8,9};
    var result = Filter(nums, num=>num%2!=0);
    //result = FilterIntegers(nums,num=>num%2==0); 
    foreach (var item in result)
    {
        Console.WriteLine(item);
    }
}
View Code

7,引入泛型擴展方法,讓代碼依賴於抽象類型而不是具體類

public static class MyExtensions
{
    //讓代碼依賴於抽象類型而不是具體類
    public static IEnumerable<T> Filter<T>(this IEnumerable<T> list, Func<T, bool> predicate)
    {
        foreach (var item in list)
        {
            if (predicate(item))
                yield return item;
        }
    }
}

// 刪除Filter<T> 這個函數,修改查找方法
static void FindOddNumbersWhere()
{
    var nums = new int[] {0,1,2,3,4,5,6,7,8,9};
    var result = nums.Where(num => num % 2 != 0).Where(num => num % 3 == 0);
    // result = nums.Filter(num => num % 2 != 0).Filter(num => num % 3 == 0);    
    foreach (var item in result)
    {
        Console.WriteLine(item);
    }
}

//可查看一下Where方法定義一致,Filter方法就實現了基類庫中Where方法
// 方法定義where一致,代碼用 Filter來替換
public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate);

8,LINQ

//LINQ 查詢與Where擴展方法,本質上是一致的,LINQ方式代碼更具有可讀性
static void FindOddNumbersLinq()
{
    var nums = new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
    var result = from num in nums
                where num%2 != 0 && num%3 == 0
                select num;
    foreach (var item in result)
    {
        Console.WriteLine(item);
    }

}

ps:寫博客真是個體力活,代碼整理了好久,佩服那些園子的大神


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM