【问题标题】:C# Select query not modifying external variableC#选择查询不修改外部变量
【发布时间】:2012-07-02 10:08:49
【问题描述】:

我有一个包含 n 个元素的类,以及一个返回元素的平方根的属性:

public double Length 
{ 
    get 
    { 
        double sum = 0.0; 
        Elements.Select(t => sum += t * t);  
        return Math.Sqrt(sum); 
    } 
}

但是,这不起作用 - 无论元素的值如何,总和都保持为 0.0。
为什么这不起作用?

注意:我已经以另一种方式实现了它,但我想了解为什么上面的代码不起作用

【问题讨论】:

    标签: c# linq


    【解决方案1】:

    LINQ 使用 deferred execution - Select Method 不会立即对所有元素执行 lambda,而是返回一个 IEnumerable<T>,它在执行时会在每个元素被枚举时执行 lambda。

    另请注意,LINQ 用于查询,而不是用于为每个元素执行代码块。您应该编写代码,使得 lambda 中没有语句,只有一个没有副作用的表达式。当您尝试计算总和时,您可以使用Sum Method

    public double Length 
    { 
        get 
        { 
            double sum = elements.Select(t => t * t).Sum();
            return Math.Sqrt(sum); 
        } 
    }
    

    public double Length 
    { 
        get 
        { 
            double sum = elements.Sum(t => t * t);
            return Math.Sqrt(sum); 
        } 
    }
    

    【讨论】:

    • 所以你是说因为指定的代码没有对Selected项有任何后续枚举,所以表达式永远不会被求值,sum也不会改变?
    • 是的,完全正确。而且你不应该仅仅为了执行 lambda 就枚举选定的项目。
    【解决方案2】:

    延迟执行。

    试试这个:

    public double Length
    {
        get { return Math.Sqrt(Elements.Sum(t => t * t)); }
    }
    

    这里立即执行 linq 查询。

    【讨论】:

    • 这实际上是我已经实施的解决方案,但没有回答导致它无法按我预期工作的其他方法的原因。
    • 我应该详细说明。 Select 语句返回一个 IEnumerable,它是在迭代 IEnumerable 后创建的。由于您从不遍历 IEnumerable,因此永远不会执行查询。因此 sum 没有被修改。
    • @3Pi:它准确地回答了为什么您的其他方法不起作用:查找延迟执行
    【解决方案3】:

    这不起作用,因为延迟执行。 你可以阅读这个

    LINQ and Deferred Execution

    Understanding LINQ's Deferred Execution

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-01-22
      • 2023-03-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多