Reputation: 305
I am new to C# and still understanding the concept of delegates. What I know of delegates is that delegates define a function signature and functions with the same signature can be added to that delegate.
public class ss
{
public delegate void sampleDelegate();
public ss()
{
sampleDelegate s1 = new sampleDelegate(sampleMethod);
s1+= new sampleDelegate(sampleMethod2);
s1();
}
public static void sampleMethod()
{
}
public static void sampleMethod2()
{
}
}
In the above code I create a delegate and give it sampleMethod and sampleMethod2. When I call s1() it calls both sampleMethod() and sampleMethod2().
What if I want to only call one of those methods and that decision is to be made at runtime?
I may be missing something very small but delegates are really confusing to understand.
Upvotes: 1
Views: 1496
Reputation: 64943
Delegates are like pointers to a method. At run-time, there's nothing that differentiates calling a delegate or a method excluding that a method is a member of an object:
some.Method();
someDelegate();
The goal of delegates is creating a blackbox where you expect some code to put some behavior, and you simply rely on a method signature.
At the end of the day, they're like method interfaces:
// It must be a parameterless method which returns no value
public delegate void Action();
// vs
// It must be a class which implements a parameterless method "Do"
// which returns no value
public interface Action
{
void Do();
}
That is, a method can't be conditionally be switched with other, but you need to use regular control flow blocks like if
or switch
to take decisions about what to do.
In order to don't duplicate Jon Skeet's answer, I'll add another possible solution:
string text = "";
sampleDelegate s1 = () =>
{
if(!string.IsNullOrEmpty(text))
{
SampleMethod1();
}
else
{
SampleMethod2();
}
};
s1();
Check that, instead of creating two instances of sampleDelegate
you can create one that handles the conditional logic to either call SampleMethod1
or SampleMethod2
.
The whole () => { }
thing is called anonymous delegate.
It can be also expressed as follows:
string text = "";
sampleDelegate s1 = delegate()
{
if(!string.IsNullOrEmpty(text))
{
SampleMethod1();
}
else
{
SampleMethod2();
}
};
But don't use above syntax... It comes from the old .NET days (.NET 1.0/1.1/2.0).
In summary, a delegate could or could not be provided as an actual class method, but you can combine class methods with anonymous delegates to meet your needs.
What if i want to only call one of those methods and that decision is to be made at runtime? I may be missing something very small but delegates are really confusing to understand.
Actually this is the reason to use delegates, but you're right when you say you're missing something.
Delegates are used to situations like the following one:
public void DoStuff(string text, Func<string, string> textFormatter = null)
{
Console.WriteLine(textFormatter != null ? textFormatter(text) : text);
}
You might call DoStuff
either this way DoStuff("hello world")
or DoStuff("hello world", text => $"<strong>{text}</strong>")
.
DoStuff
method implementation doesn't know how to format the given text, and you provide an optional parameter to give a delegate as argument that will receive the whole text to format and it will return the formatted text.
Isn't this some way conditional after all? Based on the caller, DoStuff
formats the text in a custom way. You can even provide a default format:
public void DoStuff(string text, Func<string, string> textFormatter = null)
{
// We'll give a default formatter if none is provided ;)
if(textFormatter == null)
textFormatter = text => $"<span>{text}</span>";
Console.WriteLine(textFormatter(text));
}
Upvotes: 0
Reputation: 1503270
What if i want to only call one of those methods and that decision is to be made at runtime?
Then you don't combine them together, basically. For example:
// Names changed to be more conventional
SampleDelegate s1 = someCondition
? new SampleDelegate(SampleMethod)
: new SampleDelegate(SampleMethod2);
// This will call either SampleMethod or SampleMethod2, depending on condition
s1();
Note that normally I'd use a method group conversion, but you can't use method groups for the second and third operands of the conditional operator. You could use:
SampleDelegate s1;
if (condition) {
s1 = SampleMethod;
} else {
s2 = SampleMethod2;
}
... or
SampleDelegate s1 = someCondition
? new SampleDelegate(SampleMethod)
: SampleMethod2;
Neither of these looks particularly nice to me though.
Upvotes: 3