0

So I have this methods:


public class Person
    {
        public string FirstName { get; set; }
        public int Age { get; set; }
    }

    public delegate bool filterDelegate(Person person);

     public  class Program
    {
        static void Main(string[] args)
        {
            Person p1 = new Person { FirstName = "Niels", Age = 10 };
            Person p2 = new Person { FirstName = "Margo", Age = 14 };
            Person p3 = new Person { FirstName = "Henkie", Age = 15 };
            Person p4 = new Person { FirstName = "Jan", Age = 16 };
            Person p5 = new Person { FirstName = "Jaco", Age = 20 };
            Person p6 = new Person { FirstName = "Rein", Age = 5 };


            List<Person> people = new List<Person>() { p1, p2, p3, p4, p5, p6 };


            DisplayPeople("children", people, IsChild);
            DisplayPeople("Pubers", people, isPuber);
            DisplayPeople("Adults", people, isAdult);


            Console.ReadKey();
        }

        static void DisplayPeople(string title, List<Person> people, filterDelegate filter) 
        {
            Console.WriteLine(title);
            foreach (var item in people)
            {
                if(filter(item))
                    Console.WriteLine("{0}, {1} years old", item.FirstName, item.Age);
            }

            Console.WriteLine("\n\n");
        }

        //Filters:

        static bool IsChild(Person person) 
        {
            return person.Age <= 10;        
        }

        static bool isPuber(Person person)
        {
            return person.Age > 10 && person.Age < 18;
        }

        static bool isAdult(Person person)
        {
            return person.Age >= 18;
        }
    }

And as you see it is using the delegate object. But now for my own understanding I want to write it without delegate object.

So I try it like this:


public class Person
    {
        public string FirstName { get; set; }
        public int Age { get; set; }
    }


    class Program
    {
        static void Main(string[] args)
        {

            Person p1 = new Person { FirstName = "Niels", Age = 10 };
            Person p2 = new Person { FirstName = "Margo", Age = 14 };
            Person p3 = new Person { FirstName = "Henkie", Age = 15 };
            Person p4 = new Person { FirstName = "Jan", Age = 16 };
            Person p5 = new Person { FirstName = "Jaco", Age = 20 };
            Person p6 = new Person { FirstName = "Rein", Age = 5 };


            List<Person> people = new List<Person>() { p1, p2, p3, p4, p5, p6 };

             DisplayPeople()...

        }

       static void DisplayPeople(string title, List<Person> people)
        {
            Console.WriteLine(title);

            foreach (var item in people)
            {
                Console.WriteLine($"{item.FirstName}, ${item.Age} years old");
            }
        }

        static bool IsChild(Person person)
        {
            return person.Age <= 10;
        }

        static bool isPuber(Person person)
        {
            return person.Age > 10 && person.Age < 18;
        }

        static bool isAdult(Person person)
        {
            return person.Age >= 18;
        }
    }

But so how to use the DisplayPeople() method now? There I am stuck. So what you have to do if you want to get the output of the three filter methods without delegate?

Thank you

  • 2
    Why do you not want to use delegates? – MindSwipe Jan 10 '20 at 13:45
  • You can use lambdas and Funcs to replace the delegates. – Anton Kahwaji Jan 10 '20 at 13:46
  • 1
    @AntonKahwaji [Func is simply a fancy delegate](https://learn.microsoft.com/en-us/dotnet/api/system.func-2?view=netframework-4.8), and lambdas and delegates are [different, but also not](https://stackoverflow.com/a/73819/9363973) – MindSwipe Jan 10 '20 at 13:49
  • So to see the difference. I dont want to use Func, because that is also a delegate. But just with plain methods. So how to do that? Thank you –  Jan 10 '20 at 13:53

1 Answers1

4

You can use a filter Interface and Classes instead. If that's "better" in this simple case is debatable, however.

interface PersonFilter{
    bool Pass(Person person);
}

class ChildFilter : PersonFilter
{
    public bool Pass(Person person)
    {
        return person.Age <= 10;
    }
}

class PuberFilter : PersonFilter
{
    public bool Pass(Person person)
    {
        return person.Age > 10 && person.Age < 18;
    }
}

class AdultFilter : PersonFilter
{
    public bool Pass(Person person)
    {
        return person.Age > 18;
    }
}

usage:

static void DisplayPeople(string title, List<Person> people, PersonFilter filter)
{
    Console.WriteLine(title);

    foreach (var item in people)
    {
        if ( filter.Pass(item) ) Console.WriteLine($"{item.FirstName}, ${item.Age} years old");
    }
}
// and then ...
DisplayPeople("Children", people, new ChildFilter());
DisplayPeople("Pubers", people, new PuberFilter());
DisplayPeople("Adults", people, new AdultFilter());    
Fildor
  • 14,510
  • 4
  • 35
  • 67
  • 1
    Thank you Fidor. Yes, that was I looking for. And now for me it is 100% clear , why you can use delegate. So at the end it is in fact syntactical sugar. And you don't have to write more boiler plate stuff and using interface for it. And now I also understand that the real power lies in the fact you have to use delegate with the combination of a event. –  Jan 10 '20 at 14:00
  • 1
    one correction. it is of course p.age and not person.age :) –  Jan 10 '20 at 14:04
  • I just saw it, yes. Edited. – Fildor Jan 10 '20 at 14:04
  • So in fact a delegate is a sort of class. Or it is a class –  Jan 10 '20 at 14:09
  • Microsoft says: _"A delegate is a type that represents references to methods with a particular parameter list and return type."_ [Delegates (C# Programming Guide)](https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/delegates/) Mind: a "type" is not necessarily a "class". But I am also not one of those guys that can recite the Language Specs ... As a beginner, I thought of them as some kind of similar concept to function pointers. But that's not at all correct. – Fildor Jan 10 '20 at 14:19