Reputation: 3355
I am struggling to understand delegates and for that I created a simple example for myself but it doesn't work the way I want it to, here is my example:
my functions:
class Functions
{
public string MyFname(string MyString)
{
return MyString;
}
public string MyLname(string MyString)
{
return MyString;
}
}
delegate:
class DelClass
{
public delegate string StrDelegate(string OutPutString);
public void StringCon(StrDelegate Fname,StrDelegate Lname)
{
Console.WriteLine(Fname + " " + Lname);
}
}
Main:
class Program
{
static void Main(string[] args)
{
DelClass MyDel = new DelClass();
Functions MyTster = new Functions();
DelClass.StrDelegate Name = new DelClass.StrDelegate(MyTster.MyFname);
Name("SomeVariableName");
DelClass.StrDelegate Family = new DelClass.StrDelegate(MyTster.MyLname);
Family("SomeVariableFamilyName");
MyDel.StringCon(Name, Family);
}
}
The problem is Console window doesn't show my passed string instead it shows the undermentioned text:
MyDelegateMethodInMethod.DelClass+StrDelegate MyDelegateMethodInMethod.DelClass+ StrDelegate
And when I try to invoke the passed function in StringCon body like this:
Console.WriteLine(Fname() + " " + Lname();
The compiler complain that "Delegate 'StrDelegate' does not take 0 arguments" but I don't want to pass an argument in StringCon's passed parameters, I want to do it in my Main function, is this even possible with delegates?
Upvotes: 0
Views: 2082
Reputation: 12796
This is not really how you should use delegates, delegates are mainly used as callback functions, or for EventHandlers, or when you like invoke a function.
an example of an EventHandler could be
public delegate void ReportErrorDelegate(object sender, MyCustomEventArgs e);
with a class
public class MyCustomEventArgs : EventArgs
{
// some implementation
public MyCustomEventArgs()
{
}
public MyCustomEventArgs(object argument)
: this()
{
....
}
}
and afterwards you could create an event which is based on your delegate as
public interface IRaiseMyCustomEventArgs
{
event ReportErrorDelegate CustomEventFired;
}
which you could then implement as
public class RaiseMyCustomEventArgs : IRaiseMyCustomEventArgs
{
public event ReportErrorDelegate CustomEventFired;
protected virtual void RaiseCustomEventArgs(object argument)
{
var local = CustomEventFired;
if (local != null) {
local.Invoke(this, new MyCustomEventArgs(argument));
}
}
}
an other option could be to recall a method after you detect that a UI interaction needs to be Invoked, like such
public delegate void SetTextDelegate(TextBox tb, string text);
public void SetText(TextBox tb, string text)
{
if (tb.InvokeRequired)
{
tb.Invoke(new SetTextDelegate(SetText), tb, text);
return;
}
tb.Text = text;
}
that would be called from a thread running inside a windows application (eg)
public void RunThread()
{
// assuming TextBox1 exists on the form
Thread t = new Thread(() => {
SetText(TextBox1, "Hello World");
});
t.Start();
}
Upvotes: 2
Reputation: 930
If you do not want to pass a string as input, you should declare the delegates appropriately:
class DelClass
{
public delegate string StrDelegate();
public void StringCon(StrDelegate Fname,StrDelegate Lname)
{
Console.WriteLine(Fname() + " " + Lname());
}
}
From what you wrote, you want to save the string property somewhere - but the delegate is not the place to do it.You can create an object with FName, LName properties:
class Functions
{
public string MyFname() { return MyFnameProperty; }
public string MyLname() { return MyLnameProperty; }
public string MyFnameProperty { get; set; }
public string MyLnameProperty { get; set; }
}
And finally, in Main you will write:
class Program
{
static void Main(string[] args)
{
DelClass MyDel = new DelClass();
Functions MyTster = new Functions();
DelClass.StrDelegate Name = new DelClass.StrDelegate(MyTster.MyFname);
MyTster.MyFnameProperty ="SomeVariableName";
DelClass.StrDelegate Family = new DelClass.StrDelegate(MyTster.MyLname);
MyTster.MyLnameProperty = "SomeVariableFamilyName";
MyDel.StringCon(Name, Family);
}
}
Upvotes: 2
Reputation: 54417
A delegate is an object that contains a reference to a method. Invoking the delegate has the effect of executing the method. Your two methods each have a String
parameter so to execute either of those methods you pass pass a single String
argument. That means that, when you invoke your delegates, they need to pass a single String
argument to the method they execute. Where do you think that value is going to come from? The delegate is not going to pluck it out of thin air. You have to pass it to the delegate when you invoke it. In this code:
public void StringCon(StrDelegate Fname,StrDelegate Lname)
{
Console.WriteLine(Fname + " " + Lname);
}
where are you doing that? You're not. You have to provide the arguments to the delegates in order for them to provide them to the methods:
public void StringCon(StrDelegate Fname,StrDelegate Lname)
{
Console.WriteLine(Fname("John") + " " + Lname("Doe"));
}
This is a very poor demonstration though, because your methods don't really do anything useful. How about defining a method does something useful like this:
public string GetFullName(string givenName, string familyName)
{
return givenName + " " + familyName;
}
and a corresponding delegate:
public delegate string FullNameGetter(string givenName, string familyName);
and then invoking it like so:
var fng = new FullNameGetter(GetFullName);
Console.WriteLine(fng("John", "Doe"));
Upvotes: 7