โœ… Delegates. What are they and what are they used for?

^
241 Replies
D.Mentia
D.Mentiaโ€ข3mo ago
at a basic level, a delegate is a way to reference another method. Action<T>, Func<T>, etc are delegates so if you wanted to make a method that takes in a method, void MyMethod(Action yourMethod) and does some logic, then calls yourMethod, that would be a use for a delegate
Merineth ๐Ÿ‡ธ๐Ÿ‡ช
a way to reference another method? Use methods as parameters?
D.Mentia
D.Mentiaโ€ข3mo ago
basically. Or variables
Merineth ๐Ÿ‡ธ๐Ÿ‡ช
ok, and why would we want to use methods as parameters?
D.Mentia
D.Mentiaโ€ข3mo ago
events are usually a good example. Imagine you have something like, in WinForms, OnFormShown. You can give it one of your methods, and whenever the form is shown, their internal logic calls your method
Merineth ๐Ÿ‡ธ๐Ÿ‡ช
i donโ€™t know what WinForms or OnFormShown is.
arion
arionโ€ข3mo ago
System.Linq has a bunch of methods that take delegates as parameters
stringCollection.Where(x => x.Contains("Hello"))
stringCollection.Where(x => x.Contains("Hello"))
Merineth ๐Ÿ‡ธ๐Ÿ‡ช
what is System.Linq Iโ€™m a beginner, iโ€™m mainly interested in knowing what it is and why it is used
arion
arionโ€ข3mo ago
A collection of methods that are generally centered around filtering collections
D.Mentia
D.Mentiaโ€ข3mo ago
I don't know if we can simplify it much further ๐Ÿ˜› it's if you want to pass a method to a method. Usually so that other method, which you probably don't control, can call your method at some later time instead of you calling it immediately
arion
arionโ€ข3mo ago
Like D.Mentia said above. A delegate is a pointer / reference to a function or method. Why its used? Implementations of the methods may differ but the expectation of its signature stays the same eg. void Method(string hello) (it returns nothing, and has 1 parameter)
D.Mentia
D.Mentiaโ€ข3mo ago
even in linq it's the same purpose, bool myContains(string s) { return s.Contains("Hello")} is the same thing shown above. At the time you give it to linq, you don't actually know what s is, so you can't just check right now. You have to give it the method, so it can give your method the string later, whenever it knows what it is x => x.Contains("Hello") is shorthand for defining that method, which you give to the linq .Where method, since .Where accepts a method as a parameter (a delegate/Func)
Merineth ๐Ÿ‡ธ๐Ÿ‡ช
so you call a method with another method?
arion
arionโ€ข3mo ago
you can yes
public static void MyMethod(Action<string> someDelegate)
{
// do something else first
someDelegate("Hello");
}
public static void MyMethod(Action<string> someDelegate)
{
// do something else first
someDelegate("Hello");
}
then you can do
MyMethod(s => Console.WriteLine(s));
MyMethod(s => Console.WriteLine(s));
Merineth ๐Ÿ‡ธ๐Ÿ‡ช
wow this is veeeeeeery confusing haha
D.Mentia
D.Mentiaโ€ข3mo ago
or even MyMethod(Console.WriteLine) because Console.WriteLine is a method that takes in a string and returns nothing, which is what Action<string> asks for
arion
arionโ€ข3mo ago
truee
Pobiega
Pobiegaโ€ข3mo ago
It really shouldn't be, it's simply passing a method as a parameter. That's all it is It allows you a lot of flexibility It has the same restrictions as other parameters with regards to types etc
Merineth ๐Ÿ‡ธ๐Ÿ‡ช
It does sound easy on paper, yes. Passing a method as a parameter. But our PP presentation are 50 brutal pages long so itโ€™s impossible to learn
Pobiega
Pobiegaโ€ข3mo ago
Haha Don't worry, don't panic, slow down
MODiX
MODiXโ€ข3mo ago
arion
REPL Result: Success
Action<string> funnyDelegate = Console.WriteLine;

funnyDelegate("Hi there, this is some words");
Action<string> funnyDelegate = Console.WriteLine;

funnyDelegate("Hi there, this is some words");
Console Output
Hi there, this is some words
Hi there, this is some words
Compile: 446.832ms | Execution: 23.675ms | React with โŒ to remove this embed.
arion
arionโ€ข3mo ago
pardon my bad grammar there, but u can see what we mean right?
Merineth ๐Ÿ‡ธ๐Ÿ‡ช
What is the action syntax?
arion
arionโ€ข3mo ago
An Action is a delegate of void return type
Pobiega
Pobiegaโ€ข3mo ago
You know List<T> right?
Merineth ๐Ÿ‡ธ๐Ÿ‡ช
Iโ€™ve heard of it, yes
Pobiega
Pobiegaโ€ข3mo ago
This is the same as list, but it's a delegate with no return type, instead of a collection. The type parameter is how you specify what parameters the method can take Console.WriteLine takes a single string, so it matched the type
arion
arionโ€ข3mo ago
There's nothing really special about the Action / Action<T> delegate. You can write your own delegate that does the same thing
public delegate void MySpecialAction();
public delegate void MySpecialAction();
or generics
public delegate void MySpecialAction<T>(T obj); // we ignore contravariance for brevity
public delegate void MySpecialAction<T>(T obj); // we ignore contravariance for brevity
Merineth ๐Ÿ‡ธ๐Ÿ‡ช
contravariance for brevity?
Pobiega
Pobiegaโ€ข3mo ago
Ignore that bit
arion
arionโ€ข3mo ago
dont worry about that ;)
Pobiega
Pobiegaโ€ข3mo ago
It's really hard to balance correctness with understandability at times ๐Ÿ™‚
arion
arionโ€ข3mo ago
:nod: otherwise u get moments of "Ackshually..."
Pobiega
Pobiegaโ€ข3mo ago
Yuuuup
Merineth ๐Ÿ‡ธ๐Ÿ‡ช
This is the example the show how it's used..
No description
Merineth ๐Ÿ‡ธ๐Ÿ‡ช
Still doesn't make any sense If i have two methods subtract and add, why not just call them with the parameters x and y respectively?
Pobiega
Pobiegaโ€ข3mo ago
That's just demonstrating how you use it It's not an example of a good scenario to use it in Most of the time, you use delegates to allow yourself or another programmer to have more flexibility when calling your methods Like, I made a method that took a list of things and let the caller specify how to visualize each item via a delegate This let me reuse my method everywhere, by just changing what I passed to the delegate
D.Mentia
D.Mentiaโ€ข3mo ago
Or to be able to do something later, at a specific time or in a specific scenario, instead of right now
Pobiega
Pobiegaโ€ข3mo ago
๐Ÿ‘
D.Mentia
D.Mentiaโ€ข3mo ago
Timers are probably a good example to use, you give them a method and say, run this in 10 seconds
Merineth ๐Ÿ‡ธ๐Ÿ‡ช
Ok i'll just accept that i wont get it Does Func<> and Action<> have anything to do with delegates? Action<> and Func<> Events and EventArgs EventHandler<T> Anonymous Methods Lambda expressions Anonymous types Like i'm supposed to know all this And there isn't really any YouTube videos or guide sthat explain these properly without it being convoluted or incomprehensible
D.Mentia
D.Mentiaโ€ข3mo ago
Action and Func are just simple delegates that are already made for you. Somewhere in the MS code imagine there isdelegate void Action(string s), for all the different types, so there's Action(int s), etc. except it's really just delegate void Action<T>(T s) which makes it work for all types, and that's generic types... which isn't on your list but close enough
Pobiega
Pobiegaโ€ข3mo ago
Delegates are closely related to events handlers
Merineth ๐Ÿ‡ธ๐Ÿ‡ช
hahahhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa๐Ÿ˜ญ what are you all even talking about
Pobiega
Pobiegaโ€ข3mo ago
And anonymous methods and lambda methods Bro you wrote the list
Merineth ๐Ÿ‡ธ๐Ÿ‡ช
What list?
Pobiega
Pobiegaโ€ข3mo ago
This
Merineth ๐Ÿ‡ธ๐Ÿ‡ช
Yes?
Pobiega
Pobiegaโ€ข3mo ago
And we said what parts of it delegates relate to
Merineth ๐Ÿ‡ธ๐Ÿ‡ช
I'm just looking for a simple, unconvoluted explanation which a beginner can comprehend
Pobiega
Pobiegaโ€ข3mo ago
This isn't a "beginner" topic Like, not early beginnings at least You need to grasp types and variables and methods before this makes any sense
Merineth ๐Ÿ‡ธ๐Ÿ‡ช
delegate void Action(string s) ^ This I understand. We create a function of type delegate which returns nothing (void) and takes a string s as parameter. delegate void Action<T>(T s) This i do not understand? We Make a delegate which returns nothing(void) and the name of the delegate is Action<T>???? And the parameters is of type T and variable name s?
D.Mentia
D.Mentiaโ€ข3mo ago
tbh, ChatGPT would be great at answering these
Pobiega
Pobiegaโ€ข3mo ago
T is a "type parameter"
D.Mentia
D.Mentiaโ€ข3mo ago
delegate void Action<whatever goes here>(gets_put_here s)
Pobiega
Pobiegaโ€ข3mo ago
It's a part of generic types Very important to understand It's what makes most of C# type safe
Merineth ๐Ÿ‡ธ๐Ÿ‡ช
Ok. So T = we don't know what type will be put in
Pobiega
Pobiegaโ€ข3mo ago
Yeah, it's a placeholder
Merineth ๐Ÿ‡ธ๐Ÿ‡ช
And Action? is that a function?
Pobiega
Pobiegaโ€ข3mo ago
It's your name
Merineth ๐Ÿ‡ธ๐Ÿ‡ช
from CBL
Pobiega
Pobiegaโ€ข3mo ago
Of the type
D.Mentia
D.Mentiaโ€ข3mo ago
right. Then whenever you want to use it, you'd use it like MyMethod(Action<int> yourAction) if you want to take in a method that takes an int and returns nothing
Pobiega
Pobiegaโ€ข3mo ago
Look at your two examples See how they are identical if not for the <T>
Merineth ๐Ÿ‡ธ๐Ÿ‡ช
Ok so Action is just a name. I could put delegate void Sad<T>(T s) ?
Pobiega
Pobiegaโ€ข3mo ago
Yes Action is a pre-made delegate in the BCL But if you make your own, you control the names
D.Mentia
D.Mentiaโ€ข3mo ago
yup. Then MyMethod(Sad<string> yourSadStringMethod)
Merineth ๐Ÿ‡ธ๐Ÿ‡ช
I see. Is there a difference between delegate void sad(T s) and delegate void sad<T>(T s) ?
Pobiega
Pobiegaโ€ข3mo ago
Yes, the first won't work
D.Mentia
D.Mentiaโ€ข3mo ago
the <T> has to go there if you're using it inside the ()
Pobiega
Pobiegaโ€ข3mo ago
It doesnt specify T as a type parameter
Merineth ๐Ÿ‡ธ๐Ÿ‡ช
I see. So if i don't know what the parameters type will be we use the Action<T> ?
Pobiega
Pobiegaโ€ข3mo ago
You would specify T somewhere You use T during the declaration Not during the usage
Merineth ๐Ÿ‡ธ๐Ÿ‡ช
Right, so T during declaration of parameter but usage of arguments we use proper types such as int?
Pobiega
Pobiegaโ€ข3mo ago
Yes Look at List<T> as an example When we make the class, we don't know what type the list is for But when we make a new list, we say "this is a lost of strings!"
D.Mentia
D.Mentiaโ€ข3mo ago
also it's worth mentioning that T is just a name, it can be delegate void sad<TType>(TType s) or sad<Tsadtype>(Tsadtype s) or whatever, T is just what you usually use if there's only one. And usually you always make them start with T so it's not too confusing what it is
Merineth ๐Ÿ‡ธ๐Ÿ‡ช
delegate int calculating<T>(T number1, T number2) So if i declared a delegate like this. And then made two methods for add and subtract. int Add(int number 1, int number 2) { return number1 + number2 } int Sub(int number 1, int number 2) { return number1 - number2 } To use these methods we would do it like this... int resultofAdd = calculating(Add) int resultofSub = calculating(Sub) Console.WriteLine(resultofAdd) Console.WriteLine(resultofSub) Am i thinking right?
D.Mentia
D.Mentiaโ€ข3mo ago
yes, but that's the same thing as calculating<int>(Add). In some cases you would have to specify that <int>, but in this case it can figure out that it's <int> because Add takes in ints, so it's OK to leave it out like you did
Jimmacle
Jimmacleโ€ข3mo ago
also, in this case you have to start using generic type constraints because the compiler doesn't know for sure that your T will have + and - operators
D.Mentia
D.Mentiaโ€ข3mo ago
so what you said mostly works, but that's kinda getting more complicated too I guess that means it's time to explain lambdas ๐Ÿ˜› These are all the same thing: int Add(int number1, int number2) { return number1 + number2;} int Add(int number1, int number2) => number1 + number2; calculating<int> Add = (int number1, int number2) => { return number1 + number2; } calculating<int> Add = (int number1, int number2) => number1 + number2; calculating<int> Add = (number1, number2) => number1 + number2; (Also, all of those would also work as Func<int,int,int> Add = (number1, number2) => number1 + number2;, because a Func is a method that takes in the first types and returns the last one) Lambdas are the => that's shorthand for declaring methods, and you can skip the {} if you're just returning a single line of code This is relevant because in your example, you could instead do int resultofAdd = calculating<int>((number1, number2) => number1 + number2), which is a scenario where you would actually need to give it the <int>. Or you could do int resultofAdd = calculating((int number1, int number2) => number1 + number2), and then it knows it's an int so you don't need <int> so that's what I meant by you don't need the <int> with what you did, but only because the compiler knows it's ints because Add has int parameters
Merineth ๐Ÿ‡ธ๐Ÿ‡ช
Is the delegate supposed to be green?
No description
D.Mentia
D.Mentiaโ€ข3mo ago
yep
Joschi
Joschiโ€ข3mo ago
Yes VS colors them green by default.
Merineth ๐Ÿ‡ธ๐Ÿ‡ช
Many keeps saying i should use TryParse instead of convert int numbers = TryParse(Console.ReadLine()); How come that doesn't work?
Jimmacle
Jimmacleโ€ข3mo ago
$tryparse
MODiX
MODiXโ€ข3mo ago
When you don't know if a string is actually a number when handling user input, use int.TryParse (or variants, e.g. double.TryParse)
if(int.TryParse("123", out int number))
{
var total = number + 1;
Console.WriteLine(total); // output: 124
}
if(int.TryParse("123", out int number))
{
var total = number + 1;
Console.WriteLine(total); // output: 124
}
TryParse returns a bool, where true indicates successful parsing. Remarks: - Avoid int.Parse if you do not know if the value parsed is definitely a number. - Avoid Convert.ToInt32 entirely, this is an older method and Parse should be preferred where you know the string can be parsed. Read more here
Merineth ๐Ÿ‡ธ๐Ÿ‡ช
int numbers = int.TryParse(Console.ReadLine(), out numbers); ?
Jimmacle
Jimmacleโ€ข3mo ago
no, more like
if (!int.TryParse(Console.ReadLine(), out int numbers)
{
// it goes here if the parsing failed
}
if (!int.TryParse(Console.ReadLine(), out int numbers)
{
// it goes here if the parsing failed
}
for user input you'd probably want to put this in a loop that re-prompts the user if they type something that can't be parsed
Pobiega
Pobiegaโ€ข3mo ago
and because that is annoying to do many times, its very cool to put it in a helper method like int number = AskUserForNumber("Enter your first number: ");
Jimmacle
Jimmacleโ€ข3mo ago
yeah, you can actually apply generics and delegates to this to make it very general purpose
Pobiega
Pobiegaโ€ข3mo ago
and inside that method, you'd have the loop, the tryparse, etc yep! my own version of that method uses generics and delegates to handle validation, int vs double vs decimal etc
D.Mentia
D.Mentiaโ€ข3mo ago
I'm a fan of just
do {
Console.WriteLine("Enter a number")
} while (!int.TryParse(Console.ReadLine(), out int numbers))
do {
Console.WriteLine("Enter a number")
} while (!int.TryParse(Console.ReadLine(), out int numbers))
but whatever works
Merineth ๐Ÿ‡ธ๐Ÿ‡ช
Wow even this is confusing haha
Merineth ๐Ÿ‡ธ๐Ÿ‡ช
So the int.TryParse() returns a bool.
No description
Pobiega
Pobiegaโ€ข3mo ago
yes
Merineth ๐Ÿ‡ธ๐Ÿ‡ช
what does the out do?
Jimmacle
Jimmacleโ€ข3mo ago
the out is one solution to basically return multiple things from a method in this case if the text is parsed it will store the number in numbers which is a variable that you're declaring in-line inside the method call
Merineth ๐Ÿ‡ธ๐Ÿ‡ช
ok so if the user type "2 3" will that be stored?
Jimmacle
Jimmacleโ€ข3mo ago
it will fail because that's not a number int.TryParse tries to turn the input text into a single number, if you want to parse multiple numbers you'll have to do some extra string processing first
D.Mentia
D.Mentiaโ€ข3mo ago
it'll return false, and numbers will (at that point) exist but be 0, the default value, which is why you have to do the if check. So you can tell if they actually put in 0, or if it just couldn't read a value
Merineth ๐Ÿ‡ธ๐Ÿ‡ช
So i have to loop 2 numbers?
No description
Jimmacle
Jimmacleโ€ข3mo ago
that's one solution, yeah
Merineth ๐Ÿ‡ธ๐Ÿ‡ช
How am i supposed to store them under 2 different variable names or rather, how can i apply the variable i?
Jimmacle
Jimmacleโ€ข3mo ago
either use a collection like a list or don't use a loop and just have 2 copies of your parsing code
Merineth ๐Ÿ‡ธ๐Ÿ‡ช
Ah ok I'll just have two copies of it
Jimmacle
Jimmacleโ€ข3mo ago
and if you want to still type the numbers on one line, you can have one ReadLine then Split(' ') the string into an array of multiple strings using the space as a delimiter
Merineth ๐Ÿ‡ธ๐Ÿ‡ช
So how do i use the delegeate now? I tried calc. but nothing about the delegate came up Even tho the encaps is public
Jimmacle
Jimmacleโ€ข3mo ago
the delegate itself is just a type, it describes the shape of a compatible method you need a variable of that type to do anything with it
Merineth ๐Ÿ‡ธ๐Ÿ‡ช
And i assume i can't create that inside main?
Jimmacle
Jimmacleโ€ข3mo ago
e.g. CalculateAddOrSub<int> myDelegate = calc.Add;
Pobiega
Pobiegaโ€ข3mo ago
sure you can
Pobiega
Pobiegaโ€ข3mo ago
read that error closely it does say what is wrong
Merineth ๐Ÿ‡ธ๐Ÿ‡ช
woops typo
Pobiega
Pobiegaโ€ข3mo ago
(and also check where you declared your delegate)
Merineth ๐Ÿ‡ธ๐Ÿ‡ช
lmfao i'm so confused i'm literally guessing my way through c# atm
Pobiega
Pobiegaโ€ข3mo ago
remember, delegates are types, not members
Merineth ๐Ÿ‡ธ๐Ÿ‡ช
Am i not supposed to create an instance of it?
Pobiega
Pobiegaโ€ข3mo ago
of what?
Merineth ๐Ÿ‡ธ๐Ÿ‡ช
CalculateAddOrSub
Pobiega
Pobiegaโ€ข3mo ago
its a type, so you should declare a variable of that type but look where its defined
Merineth ๐Ÿ‡ธ๐Ÿ‡ช
I have literally no clue what i'm doing
Pobiega
Pobiegaโ€ข3mo ago
what did we say about T and declaration vs usage?
Jimmacle
Jimmacleโ€ข3mo ago
the variable can hold a method that matches the signature of the delegate, so you'd assign the method that you want to call later to the delegate
Merineth ๐Ÿ‡ธ๐Ÿ‡ช
Ok so
Pobiega
Pobiegaโ€ข3mo ago
you are quite close now look at where Add is declared and is it static or not?
Merineth ๐Ÿ‡ธ๐Ÿ‡ช
No it's not static
Pobiega
Pobiegaโ€ข3mo ago
so why are you calling it as if it was?
Merineth ๐Ÿ‡ธ๐Ÿ‡ช
I assume i need an instance of it then or make it static?
Pobiega
Pobiegaโ€ข3mo ago
sure
Merineth ๐Ÿ‡ธ๐Ÿ‡ช
Well i already have an instance of the class which holds the methods
Jimmacle
Jimmacleโ€ข3mo ago
right, so how would you access an instance method of a class?
Merineth ๐Ÿ‡ธ๐Ÿ‡ช
calc.Add
Jimmacle
Jimmacleโ€ข3mo ago
exactly
Merineth ๐Ÿ‡ธ๐Ÿ‡ช
But that uses the method directly, no? And not utilize delegates
Jimmacle
Jimmacleโ€ข3mo ago
only if you call it with () without parentheses at the end it's just a reference to the method itself
Merineth ๐Ÿ‡ธ๐Ÿ‡ช
CalculateAddOrSub<int> MyAddDelegate = calc.Add;
Jimmacle
Jimmacleโ€ข3mo ago
now you can call the delegate and it will indirectly call whatever method you've assigned here
Merineth ๐Ÿ‡ธ๐Ÿ‡ช
I'm so confused lmfao i don't even know what i'm trying to do anymore
Jimmacle
Jimmacleโ€ข3mo ago
so MyAddDelegate can be used like the name of a method
Jimmacle
Jimmacleโ€ข3mo ago
you can "call" the variable and it will call whatever method is stored in the variable a more practical example here would be to ask the user what operation they want to do and store a different method in the delegate variable based on their answer
Jimmacle
Jimmacleโ€ข3mo ago
what do the errors say?
Jimmacle
Jimmacleโ€ข3mo ago
right you've declared them inside the scope of the if statements, they don't exist outside those curly braces but you don't need them, you already have val1 and val2 those are perfectly good variables
Merineth ๐Ÿ‡ธ๐Ÿ‡ช
Ok it worked That was horrible tho Delegates are awful
Jimmacle
Jimmacleโ€ข3mo ago
they aren't, this exercise is just not a practical way to use them
Merineth ๐Ÿ‡ธ๐Ÿ‡ช
Do you know any other exercise i could practice on?
MODiX
MODiXโ€ข3mo ago
Jimmacle
a more practical example here would be to ask the user what operation they want to do and store a different method in the delegate variable based on their answer
React with โŒ to remove this embed.
Jimmacle
Jimmacleโ€ข3mo ago
also look into LINQ, that makes heavy use of delegates to give you very powerful ways to work with collections the key takeaway here is that delegates allow you to write code that doesn't need to know exactly what methods it's calling to work
Merineth ๐Ÿ‡ธ๐Ÿ‡ช
I'd like to but i simply don't have time, gotta prepare for exam
Jimmacle
Jimmacleโ€ข3mo ago
which lets you write much more generalized and flexible code
Merineth ๐Ÿ‡ธ๐Ÿ‡ช
Is this what you meant? By your practial example?
Pobiega
Pobiegaโ€ข3mo ago
no have one delegate variable, but assign it add or subtract based on the users input
Merineth ๐Ÿ‡ธ๐Ÿ‡ช
Something like that?
Pobiega
Pobiegaโ€ข3mo ago
closer but not quite
// get inputs

// set up your delegate

// call the delegate

// print the result
// get inputs

// set up your delegate

// call the delegate

// print the result
your "call" should look like...
var result = myDelegate(val1, val2);
var result = myDelegate(val1, val2);
Merineth ๐Ÿ‡ธ๐Ÿ‡ช
idk anymore i'm just gpt
Pobiega
Pobiegaโ€ข3mo ago
getting real close you've set up the delegate now you just need to call it
Merineth ๐Ÿ‡ธ๐Ÿ‡ช
Ok so we set it to null since we dont know which method to use. Then we assign which method to use in the switch case? And now we call the method with val 1 and 2 ?
Pobiega
Pobiegaโ€ข3mo ago
yep
Merineth ๐Ÿ‡ธ๐Ÿ‡ช
So to summarise, delegates are used if we dont know what method to call? To me currently i dont see a point in using delegates. I would've just called the add or sub function within the switch case from my instance of Calculate Delegates seems very pointless
D.Mentia
D.Mentiaโ€ข3mo ago
This is still the same kinda bad example of a use case as before But imagine or maybe write it the other way around, where you first ask if they want to add or subtract. Then you call HandleInput(calc.Add) or (calc.Sub), and HandleInput is a method that asks for those numbers and just calls whatever method was passed to it
Jimmacle
Jimmacleโ€ข3mo ago
no, delegates are used so you don't have to know what method to call you could write some method that accepts a CalculateAddOrSub<int> as an argument and that method can call it without actually knowing where the method comes from like i said before, take a look at linq you can't call something pointless if you don't want to look at proper use cases
Merineth ๐Ÿ‡ธ๐Ÿ‡ช
Ofc i can :P seems pointless to me since in my example i could've just called the methods directly instead of using delegates
Jimmacle
Jimmacleโ€ข3mo ago
yes, in this specific example they aren't very useful but you can still see how it allows calculating a result without knowing exactly what method is being used to do the calculations
D.Mentia
D.Mentiaโ€ข3mo ago
timers are still probably a good example of when they are quite useful, if you wanted it to add those numbers 10s later, and you subtract them now, that timer has to be given a delegate so it knows what to do in 10s
Merineth ๐Ÿ‡ธ๐Ÿ‡ช
But we do know?`It's the method we assign to the delegate?
Jimmacle
Jimmacleโ€ข3mo ago
but you've introduced a separation between the code that has to know and the code that doesn't int result = MyDelegate(val1, val2) doesn't know what MyDelegate will do, and it doesn't have to
D.Mentia
D.Mentiaโ€ข3mo ago
when your programs get big and complicated, the 'you' that writes one method might be you from a month ago and not the same you that's writing the second method ๐Ÿ˜› and so that second you doesn't know what the first one does anymore
Merineth ๐Ÿ‡ธ๐Ÿ‡ช
:aaaa:
D.Mentia
D.Mentiaโ€ข3mo ago
... yeah that probably didn't help lol, what I mean is it helps you be able to split things up and not have to think about all of it you can write one method that just, asks for some numbers, and calls whatever method was given to it. And later, you (or someone else) can write the method that gets sent to it
Merineth ๐Ÿ‡ธ๐Ÿ‡ช
No like i don't think i've been more confused in my life
Jimmacle
Jimmacleโ€ข3mo ago
it will make more sense when you get more C# experience
Merineth ๐Ÿ‡ธ๐Ÿ‡ช
We wont get any more C# experience
Jimmacle
Jimmacleโ€ข3mo ago
it's a tool to abstract your code and make it more composable
Merineth ๐Ÿ‡ธ๐Ÿ‡ช
final exam is next week
Jimmacle
Jimmacleโ€ข3mo ago
you can learn C# outside of school
D.Mentia
D.Mentiaโ€ข3mo ago
often when we say things like "you don't know X", what we mean is that you should pretend you don't know X because X is handled somewhere else, it's not your job right now, and in theory someone else might be the one writing X, not you
Merineth ๐Ÿ‡ธ๐Ÿ‡ช
๐Ÿ’€ on my freetime?
Jimmacle
Jimmacleโ€ข3mo ago
i mean, yeah? if you want to i learned pretty much all of what i know in my free time is your goal to learn to program or just to pass a programming class?
Merineth ๐Ÿ‡ธ๐Ÿ‡ช
I absolutely do not want to bring my schoolwork into my freetime ๐Ÿ˜ญ
D.Mentia
D.Mentiaโ€ข3mo ago
basically pretend that every method you write is a method someone else is going to call
Merineth ๐Ÿ‡ธ๐Ÿ‡ช
I'm just looking to pass Uni
Jimmacle
Jimmacleโ€ข3mo ago
are you trying to get a job programming?
D.Mentia
D.Mentiaโ€ข3mo ago
and that someone else would find it very convenient that they can just tell you what to do in your method (by passing you a method)
Merineth ๐Ÿ‡ธ๐Ÿ‡ช
I have literally no idea what i want to do tbh Medium to high income jobs are mainly provided after a degree
Jimmacle
Jimmacleโ€ข3mo ago
yes, but i'll tell you now that programming jobs require more knowledge and practice than uni will give you
Merineth ๐Ÿ‡ธ๐Ÿ‡ช
so i just picked computer engineering program Well yeah
D.Mentia
D.Mentiaโ€ข3mo ago
and I'll recommend that if you don't like programming, don't do it as a job ๐Ÿ˜›
Merineth ๐Ÿ‡ธ๐Ÿ‡ช
every single job requires experience I enjoy programming. I don't enjoy not understanding
D.Mentia
D.Mentiaโ€ข3mo ago
but maybe you'll start to like it, you're not really at the point where it's fun yet
Jimmacle
Jimmacleโ€ข3mo ago
if you spend more time learning you'll spend less time not understanding ๐Ÿ˜›
Merineth ๐Ÿ‡ธ๐Ÿ‡ช
Easier said than done when the explanations to Delegates are 50 pages long Especially having to learn it alone
Jimmacle
Jimmacleโ€ข3mo ago
there are 5 people in this thread helping you though
D.Mentia
D.Mentiaโ€ข3mo ago
(which probably didn't make it easier :lul: )
Merineth ๐Ÿ‡ธ๐Ÿ‡ช
Yeah i know, but delegates is a hard concept to learn There really isn't a basic explanation for it
Jimmacle
Jimmacleโ€ข3mo ago
like i said, it will make more sense with more experience there is delegates are variables that hold methods instead of data
Merineth ๐Ÿ‡ธ๐Ÿ‡ช
That i know
Jimmacle
Jimmacleโ€ข3mo ago
well, that's the basic explanation ๐Ÿ˜›
Merineth ๐Ÿ‡ธ๐Ÿ‡ช
The problem is their utilization
D.Mentia
D.Mentiaโ€ข3mo ago
Deferred execution. Define a method now, let someone else (or somewhere else) run it later
Jimmacle
Jimmacleโ€ข3mo ago
then we can come up with a better example, like the console prompting and parsing mentioned earlier
Merineth ๐Ÿ‡ธ๐Ÿ‡ช
Oki
Jimmacle
Jimmacleโ€ข3mo ago
idk if @Pobiega wants to share one he has already or i'll just write a basic one quickly
var number = Prompt<int>("Enter an integer greater than 0: ", x => x > 0);
Console.WriteLine($"The number you entered: {number}");
return;

T Prompt<T>(string message, Func<T, bool> validate) where T : IParsable<T>
{
while (true)
{
Console.Write(message);
var input = Console.ReadLine();
if (T.TryParse(input, null, out var result) && validate(result))
return result;

Console.WriteLine("Invalid input. Please try again.");
}
}
var number = Prompt<int>("Enter an integer greater than 0: ", x => x > 0);
Console.WriteLine($"The number you entered: {number}");
return;

T Prompt<T>(string message, Func<T, bool> validate) where T : IParsable<T>
{
while (true)
{
Console.Write(message);
var input = Console.ReadLine();
if (T.TryParse(input, null, out var result) && validate(result))
return result;

Console.WriteLine("Invalid input. Please try again.");
}
}
Enter an integer greater than 0: abc
Invalid input. Please try again.
Enter an integer greater than 0: def
Invalid input. Please try again.
Enter an integer greater than 0: -34
Invalid input. Please try again.
Enter an integer greater than 0: 1.24
Invalid input. Please try again.
Enter an integer greater than 0: 5
The number you entered: 5
Enter an integer greater than 0: abc
Invalid input. Please try again.
Enter an integer greater than 0: def
Invalid input. Please try again.
Enter an integer greater than 0: -34
Invalid input. Please try again.
Enter an integer greater than 0: 1.24
Invalid input. Please try again.
Enter an integer greater than 0: 5
The number you entered: 5
Merineth ๐Ÿ‡ธ๐Ÿ‡ช
oh i see a lot of usage of => what does that do?
Jimmacle
Jimmacleโ€ข3mo ago
it's a lambda, basically writing a method inline so x => x > 0 is a method that matches the delegate Func<T, bool> here the delegate allows us to make Prompt check the input in the way that we need (making sure it's greater than 0) but Prompt doesn't have to know that's exactly what we want to do we can use the exact same method to get a number less than 0 just by changing the lambda to x => x < 0 hopefully that shows more how delegates can be useful to compose different behaviors together and let you make more reusable code as another example, it can get only even numbers with x => x % 2 == 0
Merineth ๐Ÿ‡ธ๐Ÿ‡ช
These are fields right, not properties?
No description
Jimmacle
Jimmacleโ€ข3mo ago
those are properties fields don't have get or set
Merineth ๐Ÿ‡ธ๐Ÿ‡ช
hmm guess i got them mixed up Is lambda just essentially = but it iterates through a list?
Jimmacle
Jimmacleโ€ข3mo ago
no, a lambda is another way to write a method (more or less) it has nothing to do with iterating or lists
Merineth ๐Ÿ‡ธ๐Ÿ‡ช
Huh
Jimmacle
Jimmacleโ€ข3mo ago
var number = Prompt<int>("Enter an integer greater than 0: ", IsGreaterThanZero);
Console.WriteLine($"The number you entered: {number}");
return;

bool IsGreaterThanZero(int number)
{
return number > 0;
}

T Prompt<T>(string message, Func<T, bool> validate) where T : IParsable<T>
{
while (true)
{
Console.Write(message);
var input = Console.ReadLine();
if (T.TryParse(input, null, out var result) && validate(result))
return result;

Console.WriteLine("Invalid input. Please try again.");
}
}
var number = Prompt<int>("Enter an integer greater than 0: ", IsGreaterThanZero);
Console.WriteLine($"The number you entered: {number}");
return;

bool IsGreaterThanZero(int number)
{
return number > 0;
}

T Prompt<T>(string message, Func<T, bool> validate) where T : IParsable<T>
{
while (true)
{
Console.Write(message);
var input = Console.ReadLine();
if (T.TryParse(input, null, out var result) && validate(result))
return result;

Console.WriteLine("Invalid input. Please try again.");
}
}
this code is functionally identical to the one i posted before but using a "regular" method instead of a lambda
D.Mentia
D.Mentiaโ€ข3mo ago
I explained them above if you need it worded a different way https://discordapp.com/channels/143867839282020352/1292841177971953674/1292859785363853395
Merineth ๐Ÿ‡ธ๐Ÿ‡ช
namespace workspace
{
internal class Program
{
static void Main(string[] args)
{
List<Person> people = new List<Person>()
{
new Person { Name = "John", Age = 25 },
new Person { Name = "Mary", Age = 32 },
new Person { Name = "Bob", Age = 19 }
};

var sorterByAge = people.OrderBy(Person => Person.Age);

}
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
}
}
namespace workspace
{
internal class Program
{
static void Main(string[] args)
{
List<Person> people = new List<Person>()
{
new Person { Name = "John", Age = 25 },
new Person { Name = "Mary", Age = 32 },
new Person { Name = "Bob", Age = 19 }
};

var sorterByAge = people.OrderBy(Person => Person.Age);

}
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
}
}
In this example They sort the list <People> for each person by the age? Isn't that Lambda?
Jimmacle
Jimmacleโ€ข3mo ago
yes, this is an example of how you can use delegates with LINQ to do certain things more easily OrderBy is a general purpose method that takes an argument of another method (using delegates) to select what to sort by Person => Person.Age is the lambda, but it doesn't do any iterating or sorting all it does is accept a person as an argument and return that person's age OrderBy does the rest of the work
Merineth ๐Ÿ‡ธ๐Ÿ‡ช
Ok so lambda is built up on something called LINQ?
Jimmacle
Jimmacleโ€ข3mo ago
no LINQ uses delegates, delegates can hold methods, lambdas are a way to write methods LINQ is a collection of methods that you can use to work on collections like OrderBy, Select, Sum, etc. they do a lot of the work for you and all you have to do is give them some extra information like what to order by, what to select, what to sum and they do that by accepting methods that take in the type of object in the collection, doing something with it, and returning something else like in your example, taking in a person and returning their age you could do the same thing with a named method
int GetPersonAge(Person person) { return person.Age; }

var sortedByAge = people.OrderBy(GetPersonAge);
int GetPersonAge(Person person) { return person.Age; }

var sortedByAge = people.OrderBy(GetPersonAge);
if that helps
Merineth ๐Ÿ‡ธ๐Ÿ‡ช
ok so lambda expressions are a way to pass anonymous methods?
Jimmacle
Jimmacleโ€ข3mo ago
exactly a lambda is basically just a method with no name
arion
arionโ€ข3mo ago
funny enough, languages like JavaScript allow for self-invoking anonymous functions eg.
(()=> console.log("Hi"))();
// Output: Hi
(()=> console.log("Hi"))();
// Output: Hi
In C# its a syntax error
MODiX
MODiXโ€ข3mo ago
arion
REPL Result: Failure
(() => Console.WriteLine("Hi"))();
(() => Console.WriteLine("Hi"))();
Exception: CompilationErrorException
- Method name expected
- Method name expected
Compile: 407.853ms | Execution: 0.000ms | React with โŒ to remove this embed.
Merineth ๐Ÿ‡ธ๐Ÿ‡ช
Ok so lambda is an anonymous method var sorterByAge = people.OrderBy(Person => Person.Age); How does it work then? We create a variable called sorterByAge as type var, and we assign it to be ...
Pobiega
Pobiegaโ€ข3mo ago
so that lambda Person => Person.Age becomes a Func<Person, int>, which means its a method that takes a person in and returns an int var isnt a real type, its just "hey compiler, figure this out"
Jimmacle
Jimmacleโ€ข3mo ago
OrderBy specifically returns an IOrderedEnumerable<T> because the other thing about LINQ is that it doesn't actually evaluate anything until you try to iterate the enumerable up until then you're basically building up a chain of operations without actually doing them
Merineth ๐Ÿ‡ธ๐Ÿ‡ช
:harold:
Jimmacle
Jimmacleโ€ข3mo ago
it's not something you normally have to think about, but asking specifically how OrderBy works starts to get complicated which is why i made the Prompt example of how delegates can be used in methods because it's much easier to understand
Merineth ๐Ÿ‡ธ๐Ÿ‡ช
Func is just a name, right?
Jimmacle
Jimmacleโ€ข3mo ago
it's a delegate type like in the base C# libraries there is a public delegate TResult Func<T1, TResult>(T1 arg1); (not exactly, but close enough)
arion
arionโ€ข3mo ago
Like action, you can write up your own version too
Merineth ๐Ÿ‡ธ๐Ÿ‡ช
I'm still a little clueless on delegates, lambda and <> :(
arion
arionโ€ข3mo ago
imo generics are a rough topic for a new programmer
Want results from more Discord servers?
Add your server