繁体   English   中英

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

[英]Why can't I assign the return of a LINQ Find() or FirstOrDefault() result?

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代码-我的观点是试图就为什么这无效是一个具体的答案。 来自文档的定义也许是关于原因的。 我不需要看如何使其正确:)

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

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

FirstOrDefault是一个Get方法,它不是数组索引器,不能使用它设置值,例如,您希望原始语句完成什么操作

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

除非它在变量中,否则以后不能将其用于任何东西。

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

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

因为您只能将值分配给变量,并且FirstOrDefault不会返回变量。

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

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

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

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

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

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

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

C#规范说=运算符:

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

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

这听起来可能令人困惑,但是请这样考虑:

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

您不能说“对于此功能,我希望您始终给我y ”( FirstOrDefault(x => x.foo) = y )。 那有点违背一个函数,该函数根据其定义返回结果! :)

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

您的问题的答案:右侧的值分配给左侧,但是对象不能位于左侧; 只有一个变量可以。

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

我假设您正在尝试检索人“ foo”,以便稍后对其进行处理。 您需要将其存储在变量中。 您的代码不是有效的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
    }
}

在代码中

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

我们看到一个分配声明。 将一个值分配给另一个。 通常,对于C风格的语言,我们称之为分配左值(左侧)或右值(或右侧)。

lvalue = rvalue.

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

如果要查找有关这些问题的更多信息,可以查看语言参考以及它们如何谈论赋值语句中的左值和右值。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM