You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

创建C#扩展函数时浮点除法运算无效问题求助

问题分析与解决方案

问题出在LINQ的延迟执行特性上,你调用的Where、OrderBy、Take都是延迟执行的LINQ方法——它们不会立即生成结果集合,而是在每次枚举(比如foreach)时才会重新执行完整的查询逻辑。

具体执行流程:

  • 当调用AddRatingToGame时,函数内的foreach会第一次枚举整个查询链,此时修改了Game对象的rating:除法操作会把原本>8的rating改成小于8。
  • 当你在主代码里再次foreach输出suggestedGames时,会第二次枚举这个查询链,此时Where(g => g.rating > 8f)会重新过滤,但此时所有目标Game的rating已经被改成小于8,自然没有元素输出。
  • 乘法操作之所以正常,是因为乘法后rating变得更大,第二次枚举时Where条件依然满足,所以能输出结果。

解决方案

在调用AddRatingToGame之前,把延迟执行的查询转为立即执行的内存集合,比如用ToList()或者ToArray(),这样查询只会执行一次,后续操作都是在固定集合上进行:

修改主代码:

//providing the random values to the player 
var suggestedGames = gameList.Where(g => g.rating > 8f)
                            .OrderBy(g => _random.Next())
                            .Take(3)
                            .ToList() // 转为立即执行的List,固定查询结果
                            .AddRatingToGame();
// takes 3 random values with 8.0 above rating
Console.WriteLine("\nsuggested games:");

foreach(var game in suggestedGames)
{
    Console.WriteLine(game.name);   
}

也可以直接修改扩展函数,在内部处理为立即执行的集合,避免外部忘记调用ToList:

public static class Helpers
{
    public static IEnumerable<Game> AddRatingToGame(this IEnumerable<Game> games)
    {
        var gameList = games.ToList(); // 立即枚举并转为List,避免重复执行查询
        foreach(var game in gameList)
        {
            game.rating = game.rating / 2f;
            game.name = $"{game.name} - {game.rating}";
        }
        return gameList;
    }
}

额外优化建议

直接修改原对象的属性容易产生副作用,如果你不想改动原数据,可以考虑创建新的Game对象返回,彻底规避延迟执行的问题:

public static IEnumerable<Game> AddRatingToGame(this IEnumerable<Game> games)
{
    foreach(var game in games)
    {
        var newRating = game.rating / 2f;
        yield return new Game($"{game.name} - {newRating}", newRating);
    }
}

内容的提问来源于stack exchange,提问作者ib_magar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 12:45:36