4

It's my first time using LINQ and I don't really get it yet.

I tried to understand it via an example but I need some help.

I created a class "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;
    }
}

I created a list of "people":

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));

Now I would like to get out every person which is set as a parent. But I'm stuck here:

var parents = people.Where()
1
  • var parents = people.Where(p => p.parent); will return all results where parent property is true . In this case, parent is a bool type and you can evaluate it without == or Equals, but, for non boolean properties you should use the equality comparison. Commented May 12, 2016 at 13:35

3 Answers 3

9

The linq statement should be

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

and change private bool parent { get; set; } to public bool parent { get; set; }

Sign up to request clarification or add additional context in comments.

3 Comments

Alright I think I fightet with it cause all the properties of the Person class are set to private. What if I would like to keep it like that? Is there also a solution for this? But thanks!
@Mr.Toast You could expose it as a read only property public bool parent { get; private set; }. That way you can see if the person is a parent, but not mutate it.
@Mr.Toast no you need at least reading access to the property you want to filter
4
var peopleWithParents = people.Where(x => x.parent == true).ToList();

Although it may take a little while to get your head around, the syntax is pretty simple, and becomes really comfortable to use. Keep in mind that 'where' acts as a filter, and 'select' acts as a projection. Remember that you will need the properties to be publicly visible. You can keep the setters private if you like. You could even introduce a method to check that the parent exists, and call it in the lambda.

Let's say hypothetically that your person class was more complex.

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;
    }
}

You could do something like this to get a list of person objects representing all the parents:

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

or

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

You also don't need to use 'x', and this letter is only in scope within each clause; could even order these parents by age:

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

Maybe you would like to get the oldest parent from the above collection:

var oldestParent = parents.OrderByDescending(x => x.age).FirstOrDefault();

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

You can combine multiple checks in your query:

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

Also recall that in C# you generally Capitalise the first letter of properties. Eg:

public bool Child { get; private set; }

4 Comments

Thanks for this detailed description! Very helpful
No problem. I recall when I was first learning LINQ and Lambda, I struggled; what made it easier for me was using a Visual Studio add-on called ReSharper. It is quite popular in the industry, and although it can feel a little uncomfortable at first (to use), it will suggest better ways for you to write code, often taking advantage of LINQ, and generally make you a better developer. If you are a student, head to JetBrain's website, and get it free for a year, otherwise try the 30 day trial.
I'm already using it :) curious to see what it can do regarding LINQ and Lambda!
Write some foreach loops and see what it suggests. :)
1

The LINQ is quite straight-forward:

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

However, your parent may not be accessible due to its access modifier.

If you don't want it to be changed from outside once declared (and that's likely the reason why you declare the properties by the constructor's parameters). I recommend you to use 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;
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.