C
C#2y ago
IcyIme

❔ problem with understanding delegates and generics

I have a problem with understanding delegates and generics and I'm already spending a lot of time on it and I don't understand where and in what situations to use it and why it's used and what it's good for... I went through several sources and none of them helped, thanks in advance for your help and i forgot interfaces
31 Replies
Loup&Snoop
Loup&Snoop2y ago
the two are very different things
Angius
Angius2y ago
Generics are simple. Let's take collections, for example, a List<T>. List<int> tells us it's a list of integers, while List<Person> tells us it's a list of Persons
Loup&Snoop
Loup&Snoop2y ago
the point of a generic is to define something that can work with ANY type, but not every type at once
Angius
Angius2y ago
The List might have, say, an array underneath, like
public class List<T>
{
private T[] _values;
// other code
}
public class List<T>
{
private T[] _values;
// other code
}
So generics let you pass the type itself to a class or a method
Loup&Snoop
Loup&Snoop2y ago
so as ZZZZZ says, you can define a List<int> or List<string>, and they are both lists, and they have all the methods for lists but a List<string> takes strings, and List<int> takes ints
Angius
Angius2y ago
Delegates, meanwhile, let you pass methods/functions as parameters Taking LINQ as example, numbers.Select(num => num * 2) will execute the anonymous method on every element of the numbers collection In this case, it will multiply each by 2 Or a numbers.Where(x => x % 2 == 0) which will execute the anonymous function on every element of the numbers collection, and return only the elements for which the function returns true
IcyIme
IcyImeOP2y ago
this is code of example and i am confused
IcyIme
IcyImeOP2y ago
Angius
Angius2y ago
There are neither generics nor delegates in this code
IcyIme
IcyImeOP2y ago
i know this is about delegates and when i went to official documentation microsoft have with generics and its confusing
Loup&Snoop
Loup&Snoop2y ago
Imagine a delegate is like a list of functions. You can define: public delegate string MyDelegate(int x); Now you just defined a type of object, which is a container of functions. The functions allowed in this type of container are functions that take in 1 int, and output a string. you haven't made a container yet. It's like we just defined a class. You still with me?
Angius
Angius2y ago
Ah, yeah, I see a delegate in the code sample, disregard what I said
Loup&Snoop
Loup&Snoop2y ago
now we can make a delegate: MyDelegate thisIsAContainer thisIsAContainer is a MyDelegate, which is a container of functions where 1 int goes in, and 1 string comes out and we can make more of them MyDelegate thisIsAnotherContainer MyDelegate thisIsAThirdContainer
IcyIme
IcyImeOP2y ago
so if i uderstant right delegates this is the delegate how use?
using System;

namespace ConsoleApp3;

class Program
{
public delegate bool FilterDelegate(person p);

public static void Main()
{
person p1 = new person() { Name = "Aiden", Age = 41 };
person p2 = new person() { Name = "Sif", Age = 69 };

List<person> people = new List<person>() { p1, p2 };

DisplayPeople("Kids", people, IsMinor);
DisplayPeople("Adults", people, IsAdult);
DisplayPeople("Senior", people, IsSenior);

}

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

foreach (person p in people)
{
if (filter(p))
{
Console.WriteLine($"{p.Name}, {p.Age} years old");
}
}
}

static bool IsMinor(person p)
{
return p.Age < 18;
}

static bool IsAdult(person p)
{
return p.Age >= 18;
}

static bool IsSenior(person p)
{
return p.Age >= 65;
}
}
using System;

namespace ConsoleApp3;

class Program
{
public delegate bool FilterDelegate(person p);

public static void Main()
{
person p1 = new person() { Name = "Aiden", Age = 41 };
person p2 = new person() { Name = "Sif", Age = 69 };

List<person> people = new List<person>() { p1, p2 };

DisplayPeople("Kids", people, IsMinor);
DisplayPeople("Adults", people, IsAdult);
DisplayPeople("Senior", people, IsSenior);

}

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

foreach (person p in people)
{
if (filter(p))
{
Console.WriteLine($"{p.Name}, {p.Age} years old");
}
}
}

static bool IsMinor(person p)
{
return p.Age < 18;
}

static bool IsAdult(person p)
{
return p.Age >= 18;
}

static bool IsSenior(person p)
{
return p.Age >= 65;
}
}
Loup&Snoop
Loup&Snoop2y ago
ok, now we're going to fill these containers with functions. thisIsAContainer += TurnMyIntIntoAString; I just added TurnMyIntIntoAString into the container. thisIsAContainer -= TurnMyIntIntoAString; and I just took it out
Angius
Angius2y ago
Yeah, that seems correct Besides the Person type being lowercase
IcyIme
IcyImeOP2y ago
my bad ngl
Loup&Snoop
Loup&Snoop2y ago
nothing seems to fill that container in this block of code tho
IcyIme
IcyImeOP2y ago
why make this i confused of this somewhere used
delegate string mydelegate(int x);
mydelegate _del = null;
_del = new mydelegate(20);
delegate string mydelegate(int x);
mydelegate _del = null;
_del = new mydelegate(20);
Angius
Angius2y ago
Dementia Other than that, I see no reason for this code existing
Loup&Snoop
Loup&Snoop2y ago
I don't understand mydelegate(20) gives a string _del is a mydelegate
Angius
Angius2y ago
Never in my life have I seen delegates being newed up
Loup&Snoop
Loup&Snoop2y ago
the last part I didn't mention on delegates is if you call the delegate like a function, then it calls everything in the container
IcyIme
IcyImeOP2y ago
IcyIme
IcyImeOP2y ago
thanls thanls and where to use? (use cases)
Loup&Snoop
Loup&Snoop2y ago
I have a game with a level editor. Let's say I draw something. My BuildingCreator class handles drawing. When I draw, i want other classes to do things, like update my UI (like sort my tileBar to show the most recent thing first, or light up a selection etc). Problem: The class that handles the UI is different, and I don't have direct access all the time. And I ONLY want to call the code to light things up when something new is drawn. I do not want to run a code in an Update loop that runs code every single frame to check if something new is on the board or something. That's wasteful Instead, my BuildingCreator has a delegate called OnObjectDrawn, which is a public variable. the only thing BuildingCreator does with OnObjectDrawn is: 1) Instantiate the variable, and 2) call it when something gets drawn. and by call it, I mean anything in that container gets called Then my UI scripts can add functions to that container, so they can get called at that same time so my UI will have something like: buildingCreator.OnObjectDrawn += HighlightMenuButton; and then every time we draw, OnObjectDrawn calls everything inside itself, which includes HighlightMenuButton. Even though that function does not appear at all in the file of BuildingCreator, which is oblivious to what exactly is in that delegate Continued use case: I have more and more UI elements, or player stuff, or SFX etc. that I want to trigger whenever something gets drawn. Instead of digging through the guts of BuildingCreator every time I want to make drawing call something new, I can just have other things keep adding their functions to that delegate At the end of the project, OnObjectDrawn could have like 20 functions that I never knew I'd need to plan for at the start. Does that make sense?
Valwex
Valwex2y ago
When should you use delegate instead of event?
Loup&Snoop
Loup&Snoop2y ago
you need access to the delegate to use it outside. public lets you do whatever you want with the variable. event only lets you += or -= with the delegate variable so if a delegate is an event, another function isn’t allowed to just wipe it, or whatever.
Valwex
Valwex2y ago
A delegate that encapsulates a single method is of little use in the end? The goal is to have lots of methods that a delegate will call
Loup&Snoop
Loup&Snoop2y ago
you can use it as much or as little as you like. But if you just have one connection to manage, then you can just code in the link between the two objects. in other ways Another use case is input events. You could have a ton of different parts in your game that are all constantly running “If jump button pressed” every frame. Or you could have an event that everyone subscribes to, to then call what is needed when it is needed because you only press a jump button like once every 3 seconds or something, vs doing an update loop 60 times a second all the time for everything you could probably also just use it as a variable to hold a simgle function, which changes reference to which function is supposed to be called. There’s an example of that above.
Accord
Accord2y ago
Was this issue resolved? If so, run /close - otherwise I will mark this as stale and this post will be archived until there is new activity.

Did you find this page helpful?