LINQ的魔幻与禁忌:5个让你既爱又恨的"骚操作

作者:微信公众号:【架构师老卢】
6-7 9:1
12

LINQ的使用,往往在"巧妙"与"邪恶"之间只有一线之隔。

我曾深刻领悟这一点——在一次代码评审中,我自信满满地展示了一段自认为堪称艺术品的LINQ代码,结果看着资深开发者的表情逐渐扭曲。"这……确实能跑,"他缓缓说道,"但今晚我可能会因为这段代码失眠。"

LINQ不仅是一种工具,更是一种武器。 而任何武器,既能行善,也能作恶。

以下是我用过的5个最具争议的LINQ技巧(后来恨不得从未写过):


1. 副作用手枪(在Select中执行代码)

var processedOrders = orders.Select(order => {  
    order.Total = ApplyRegionalTax(order.Total);  
    AuditLog.Write($"Processed: {order.Id}");  
    return order;  
}).ToList();

为何邪恶?
LINQ本应只用于查询,而非执行副作用。Select 应该是纯函数——仅处理数据,而非记录日志或修改状态。

正确做法:先处理集合,再投影

foreach (var order in orders)  
{  
    order.Total = ApplyRegionalTax(order.Total);  
    AuditLog.Write($"Processed: {order.Id}");  
}  
var processedOrders = orders.ToList();

2. ToList() 诱饵陷阱(强制提前执行)

var results = dbContext.Products  
    .Where(p => p.IsActive)  
    .ToList()  // ← 邪恶的天才时刻  
    .Select(p => ExpensiveTransformation(p));

为何邪恶?
ToList() 会先将所有活跃产品加载到内存,再执行转换。如果数据量大,性能直接爆炸。

正确做法:让数据库先过滤

var results = dbContext.Products  
    .Where(p => p.IsActive)  
    .AsEnumerable()  // 在数据库过滤后切换至LINQ-to-Objects  
    .Select(p => ExpensiveTransformation(p));

3. SelectMany 地雷(嵌套循环失控)

var allPermissions = users  
    .SelectMany(u => u.Roles)  
    .SelectMany(r => r.Permissions)  
    .Distinct();

为何邪恶?
如果 UsersRoles 数据量大,这会引发笛卡尔积爆炸。更糟的是,由于延迟执行,爆炸可能发生在远离代码的地方。

正确做法:尽早物化或重构查询

var roleIds = users.SelectMany(u => u.Roles).Select(r => r.Id).Distinct();  
var permissions = dbContext.Permissions.Where(p => roleIds.Contains(p.RoleId));

4. Aggregate 陷阱(隐藏的复杂度炸弹)

var csvLine = orders.Aggregate("", (acc, order) => $"{acc},{order.Id}");

为何邪恶?
Aggregate可读性黑洞,且会生成N次字符串分配(GC压力警告⚠️)。

正确做法:像文明人一样用 string.Join

var csvLine = string.Join(",", orders.Select(o => o.Id));

5. 空条件运算符的混乱(?. 在LINQ中的滥用)

var customerNames = orders  
    .Select(o => o.Customer?.Name ?? "Ghost Customer")  
    .ToList();

为何邪恶?
LINQ中的空检查会掩盖数据问题。如果 Customernull,这是否是Bug?查询默默掩盖了它。

正确做法:快速失败或先过滤

var validOrders = orders.Where(o => o.Customer != null);  
var customerNames = validOrders.Select(o => o.Customer.Name);

"能力越大,责任越大。"
LINQ赋予我们强大的表达能力,但滥用会导致代码变得晦涩、低效,甚至埋下隐藏Bug。

你曾经写过哪些"创意十足"的LINQ技巧? 😈

相关留言评论
昵称:
邮箱:
阅读排行