I'm slowly getting my head around delegates, in that the signature of the delegate must match that of the method it is delegating too.
However, please review the following code.
public static void Save()
{
ThreadStart threadStart = delegate
{
SaveToDatabase();
};
new Thread(threadStart).Start();
}
private static void SaveToDatabase() { }
I am now stumped at this point, because the delegate returns void
(as that is what SaveToDatabase()
is) but, it's clearly returning a ThreadStart
... Or is it?
If I were to write my own delegate, I would have no idea how to achieve this because the delegate would have to be void to match the return type of SaveToDatabase()
. But it can't be; it would be of type ThreadStart
!
My question is, have I totally mis-understood or is this made possible by some .NET trickery? If I wanted to write this method but create my own delegate, how would I ?
The word "delegate" is a bit abused. It's easier with classes and objects. A "class" is like a blueprint for an object. An "object" is an actual instance in memory, which follows the blueprint of the class.
For delegates we use the same word, hence I suspect your confusion. Consider the following code:
class Main
{
public delegate int DelegateType(string x);
public int SomeFunction(string y) { return int.Parse(y)*2; }
public void Main()
{
DelegateType delegateInstance = null;
delegateInstance = SomeFunction;
int z = delegateInstance("21");
Console.WriteLine(z);
}
}
This code outputs "42".
The DelegateType
is the type of the delegate. Like a class is a blueprint for an object, the delegate is a blueprint for a function.
So later we create a variable named delegateInstance
which is of the type DelegateType
. To that variable, we can assign ANY function that takes a single string parameter and returns an integer. Note, that we assigned the function itself, not the results of that function. It's like the delegateInstance
variable is now a synonym of that function. Indeed, as demonstrated a line later, we can now use delegateInstance
to call that funcion! Just as if delegateInstance
was a function itself. But, since it is variable, we can also do all the same things that we usually do with variables - like pass them as parameters to other functions, or even return from other functions (A function that returns a function! Wrap your head around that!)
OK, let's see the code that baffled you.
public static void Save()
{
ThreadStart threadStart = delegate
{
SaveToDatabase();
};
new Thread(threadStart).Start();
}
private static void SaveToDatabase() { }
First thing to notice is that you used an anonymous delegate
. Another misuse of the term. When compiled, it results in something like this:
public static void Save()
{
ThreadStart threadStart;
threadStart = __ASDASDASD6546549871;
var tmp = new Thread(threadStart);
tmp.Start();
}
private static void SaveToDatabase() { }
private void __ASDASDASD6546549871()
{
SaveToDatabase();
}
Note that your anonymous function was actually transformed to a completely regular function with a random name, and then that function was assigned to the threadStart
variable.
So now this is just like the example above. Just replace DelegateType
with ThreadStart
, delegateInstance
with threadStart
and SomeFunction
with __ASDASDASD6546549871
.
Does it make sense now?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With