首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

C# List.ForEach 編譯錯誤:匿名委託與 Lambda 表達式的類型推導差異

     編輯:程式設計綜合問答

錯誤代碼


var prizeGroup = prizeDetailCollection
    .GroupBy(m => m.UserId, (key, c) => new {
        Key = key,
        C1 = c.Sum(n => n.Currency_1),
        C2 = c.Sum(n => n.Currency_2) + c.Sum(n => n.Currency_10)
    })
    .ToList();

prizeGroup.ForEach(delegate(var item) { // CS0815: 無法將匿名方法轉換為 System.Action<...>
    if (item.C1 > 0m) { }
    if (item.C2 > 0m) { }
});

原因分析

`List.ForEach` 接受 `Action` 委託。C# 匿名方法(`delegate` 關鍵字)不支持隱式類型參數 `var`,編譯器無法推導 `item` 的類型,導致類型推導失敗。

修正方案


// 方案 1:Lambda 表達式(推薦,類型推導自動)
prizeGroup.ForEach(item => {
    if (item.C1 > 0m) { /* ... */ }
    if (item.C2 > 0m) { /* ... */ }
});

// 方案 2:顯式指定類型的匿名方法
prizeGroup.ForEach(delegate(AnonymousType item) { ... }); // 匿名類型無法命名,不可行

// 方案 3:foreach 語句(最通用、可讀性最好)
foreach (var item in prizeGroup) {
    if (item.C1 > 0m) { }
    if (item.C2 > 0m) { }
}

知識點補充

  • `var` 僅用於局部變量聲明,不能用於參數列表、返回類型、字段聲明。
  • Lambda 表達式 `item => ...` 編譯器根據 `List` 的 `T` 自動推導參數類型。
  • 匿名類型(`new { Key, C1, C2 }`)僅在方法內部可用,跨方法傳遞需定義具名類型或 `record` (C# 9+)。

代碼優化建議


// 使用 record 定義分組結果類型(C# 9+)
public record PrizeGroupResult(Guid Key, decimal C1, decimal C2);

// 查詢投影為強類型
var prizeGroup = prizeDetailCollection
    .GroupBy(m => m.UserId)
    .Select(g => new PrizeGroupResult(
        g.Key,
        g.Sum(n => n.Currency_1),
        g.Sum(n => n.Currency_2) + g.Sum(n => n.Currency_10)
    ))
    .ToList();

foreach (var item in prizeGroup) { /* 業務邏輯 */ }
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved