为什么我不能分配LINQ Find()或FirstOrDefault()结果的返回值?

时间:2016-03-18 18:30:25

标签: c# linq

class Program
{
    static void Main(string[] args)
    {
        var people = new List<Person>
        {
            new Person { Name = "foo" },
            new Person { Name = "bar" }
        };

        // ERROR: Left-hand side must be a variable, property, or indexer
        people.FirstOrDefault(x => x.Name == "foo") = new Person();
    }
}

public class Person
{
    public string Name { get; set; }
}

为什么上面的FirstOrDefault行无效.NET代码?如果FirstOrDefault()的返回不是变量,那么它是什么?

编辑:我理解如何制作这个有效的.NET代码 - 我的观点是试图得到一个具体的答案,说明为什么这是无效的。从文档的定义或许为什么。我不需要看看如何纠正它:)

7 个答案:

答案 0 :(得分:4)

您无法分配函数的返回,您需要将其存储在变量

var person = people.FirstOrDefault(x => x.Name == "foo") ?? new Person();

FirstOrDefault是一个Get方法,它不是一个数组索引器,你不能用它来设置值,例如你期望你的原始语句完成什么

 people.FirstOrDefault(x => x.Name == "foo") = new Person();

在变量之前,你不能将它用于任何事情。

如果要在方法中设置必须使用out参数或引用或属性,则返回用于返回值的方法。

答案 1 :(得分:4)

  

为什么上面的FirstOrDefault行无效.NET代码?

因为您只能为变量赋值,而FirstOrDefault不会返回变量。

  

如果FirstOrDefault()的返回不是变量,它是什么?

这是一个价值。您可以将FirstOrDefault的结果存储在变量中,它本身不是变量

答案 2 :(得分:2)

如果要分配给列表的第一个元素,则只需在索引处访问它:people[0] = new Person()

要回答你的另一个问题,这不是一个变量;这是一个对象。想象一下,我试着写"foo" = "bar"。这会引发异常 - 将字符串文字分配给另一个字符串是什么意思?您的代码在逻辑上是等效的。

答案 3 :(得分:1)

在C#(当前)中,您无法为函数调用设置值。相反,你应该说:

var person = people.FirstOrDefault(x => x.Name == "foo");

if (person != null) {
    person = new Person();
}

C#规范说=运算符:

  

将其右侧操作数的值存储在由其左侧操作数表示的存储位置,属性或索引器中,并将该值作为其结果返回(https://msdn.microsoft.com/en-us/library/sbkb459w.aspx

函数调用不是存储位置,属性或索引器。

这可能听起来令人困惑,但请以这种方式思考:

=运算符是赋值。 x = y表示,当您要求x时,请给我y(记住基本代数?)。

你不能说,&#34;对于这个功能,我希望你总是给我y&#34; (FirstOrDefault(x => x.foo) = y)。这有点违背了一个函数,它根据它的定义返回一个结果! :)

答案 4 :(得分:1)

FirstOrDefault()是方法调用,不能用作变量。

回答你的问题:右手边的值分配到左手边,但是物体不能在左手边;只有变量才可以。

您正尝试将FirstOrDefault()方法的结果分配给People类构造函数。

答案 5 :(得分:0)

我认为你正试图找回那个人&#34; foo&#34;以后再做点什么。您需要将其存储在变量中。您的代码无效C#语法。

class Program
{
    static void Main(string[] args)
    {
        var people = new List<Person>
        {
            new Person { Name = "foo" },
            new Person { Name = "bar" }
        };

        var fooPerson = people.FirstOrDefault(x => x.Name == "foo");

        // Use fooPerson
    }
}

答案 6 :(得分:0)

代码中的

people.FirstOrDefault(x => x.Name == "foo") = new Person();

我们看到了一个赋值语句。将一个值分配给另一个。通常使用C风格的语言,我们称之为左值(左侧)左值(或右侧)。

lvalue = rvalue.

左值和右值可以有限制。 rvalue必须能够被评估为与左值相同的类型,并且左值必须是内存中的位置(有时称为变量。)

如果您想了解有关这些问题的更多信息,可以查看语言参考以及他们如何在赋值语句中讨论左值和右值。