C# LINQ 列表过滤

4

这是我第一次使用LINQ,我还不太理解。

我尝试通过一个例子来理解它,但我需要一些帮助。

我创建了一个名为“Person”的类:

class Person
{
    private string name { get; set; }
    private int age { get; set; }
    private bool parent { get; set; }
    private bool child { get; set; }

    public Person(string name, int age, bool parent, bool child)
    {
        this.name = name;
        this.age = age;
        this.parent = parent;
        this.child = child;
    }
}

我创建了一个“人”列表:
people.Add(new Person("Joel", 12, false, true));
        people.Add(new Person("jana", 22, false, false));
        people.Add(new Person("Stefan", 45, true, false));
        people.Add(new Person("Kurt", 25, false, false));
        people.Add(new Person("Sebastian", 65, true, false));
        people.Add(new Person("George", 14, false, true));
        people.Add(new Person("Noel", 50, true, false));

现在我想找出所有被设置为父级的人。 但是我卡在这里:

var parents = people.Where()

var parents = people.Where(p => p.parent); 将返回所有 parent 属性为 true 的结果。在这种情况下,parent 是一个 bool 类型,您可以在不使用 ==Equals 的情况下对其进行评估,但是对于非布尔类型的属性,您应该使用相等性比较 - mihai
3个回答

9

这个linq语句应该是:

var parents = people.Where(x => x.parent);

private bool parent { get; set; }改为public bool parent { get; set; }

,涉及IT技术。

好的,我认为我与它战斗了,因为Person类的所有属性都设置为私有。如果我想保持这样怎么办?也有解决方案吗?但还是谢谢! - Mr. Toast
@Mr.Toast 您可以将其公开为只读属性 public bool parent { get; private set; }。这样,您就可以查看该人是否是父母,但不能更改它。 - juharr
@Mr.Toast 不,你至少需要读取要筛选的属性的访问权限。 - fubo

4
var peopleWithParents = people.Where(x => x.parent == true).ToList();

尽管需要一些时间来理解,但其语法十分简单且易于使用。请记住,“where”起到过滤器的作用,“select”则用于投影。请注意,属性需要是公开可见的。如果愿意,可以将设置器保持为私有。甚至可以引入检查父级是否存在的方法,并在lambda中调用它。
假设你的person类更加复杂。
class Person
{
    public string name { get; private set; }
    public int age { get; private set; }
    public Person parent { get; private set; }
    public bool child { get; private set; }

    public bool HasParent()
    {
        return parent != null;
    }

    public Person(string name, int age, Person parent, bool child)
    {
        this.name = name;
        this.age = age;
        this.parent = parent;
        this.child = child;
    }
}

您可以通过以下方式获得一个人对象列表,该列表表示所有父母:

您可以这样做,获取代表所有父母的人对象列表:

var parents = people.Where(x => x.parent != null).Select(x => x.parent).ToList();

或者

var parents = people.Where(x => x.HasParent()).Select(x => x.parent).ToList();

您也不需要使用“x”,这个字母只在每个从句中有效;甚至可以按年龄对这些家长进行排序:

var parents = people.Where(y => y.HasParent()).Select(z => z.parent).OrderBy(x => x.age).ToList();

也许你想从上述集合中获取最老的父级:
var oldestParent = parents.OrderByDescending(x => x.age).FirstOrDefault();

if (oldestParent != null)
{
    Console.WriteLine($"{oldestParent.name} is the oldest, at {oldestParent.age}");
}

您可以在查询中组合多个检查条件:

var parentsOfPeopleWithChildren = people.Where(x => x.parent != null && x.child).Select(x => x.parent).ToList();

请记住,在C#中,通常将属性的第一个字母大写。例如:
public bool Child { get; private set; }

非常感谢您提供的详细说明!非常有帮助。 - Mr. Toast
没问题。我还记得当我第一次学习LINQ和Lambda时,我很困难;让我感觉更容易的是使用一个名为ReSharper的Visual Studio插件。它在行业中非常受欢迎,虽然一开始可能会感到有点不舒服(使用),但它会建议更好的编写代码方式,通常利用LINQ,并使您成为更好的开发人员。如果您是学生,请前往JetBrain的网站,免费获取一年,否则请尝试30天的试用版。 - Élie
我已经在使用它了 :) 很好奇它在LINQ和Lambda方面能做些什么! - Mr. Toast
写一些foreach循环并查看它的建议。 :) - Élie

1

LINQ相当直观:

var query = people.Where(x => x.parent);

然而,由于其访问修饰符,您的“parent”可能无法访问。
如果您不希望在声明后从外部更改它(这很可能是您通过构造函数参数声明属性的原因),我建议您使用“public { get; private set; }”。
class Person
{
    public string name { get; private set; }
    public int age { get; private set; }
    public bool parent { get; private set; }
    public bool child { get; private set; }

    public Person(string name, int age, bool parent, bool child)
    {
        this.name = name;
        this.age = age;
        this.parent = parent;
        this.child = child;
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接