Reputation: 26812
I have a class with a method in which a string will be passed. That method will do some things to that string and it then passes the string to a certain object which can do other things with the string.
So it basically looks like this:
class Main
{
public Main()
{
strClass str = new strClass(this);
}
public function handler ( )
{
console.log("No string is passed yet, but this method is called from receiveData()");
}
}
class strClass
{
object handler;
public strClass ( handler )
{
// save the object
this.handler = handler;
}
public receiveData ( string str )
{
// This method does some stuff with the string
// And it then passes it on to the supplied object (handler) which will do
// the rest of the processing
// I'm calling the "handler" method in the object which got passed in the
// constructor
Type thisType = this.handler.GetType();
MethodInfo theMethod = thisType.GetMethod("handler");
theMethod.Invoke(this.handler, null);
}
}
Now this code works good, with the reflection stuff. But i was wondering, shouldn't this be possible (and maybe even better?) with delegates?? If so, how can i implement this by using a delegate instead?
Upvotes: 1
Views: 265
Reputation: 23310
Basically, you want to change how your StrClass
object react to data begin received. Sounds like events to me.
something like this, where you have handling methods both in the Main
and in a generic HandlerObject
:
class StrClass : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged = null;
public void OnPropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (PropertyChanged != null)
PropertyChanged(this, e);
}
private string receivedString;
public string ReceivedString
{
get;
set
{
string oldStr = receivedString;
receivedString = value;
PropertyChanged(receivedString, new PropertyChangedEventArgs("ReceivedString"));
}
}
public void receiveData(string str)
{
//event fires here
ReceivedString = str;
}
}
class HandlerObject
{
public void HandlerMethod1(string s)
{
//magic
}
public void HandlerMethod2(string s)
{
//different kind of magic
}
}
class Program
{
static void HandlerMethod3(string s)
{
//another kind of magic!
}
static void Main(string[] args)
{
StrClass class1 = new StrClass();
StrClass class2 = new StrClass();
StrClass class3 = new StrClass();
HandlerObject handler = new HandlerObject();
class1.PropertyChanged += (s, e) => { handler.HandlerMethod1(s.ToString()); };
class2.PropertyChanged += (s, e) => { handler.HandlerMethod2(s.ToString()); };
class3.PropertyChanged += (s, e) => { HandlerMethod3(s.ToString()); };
}
}
Upvotes: 0
Reputation: 12468
You can do it with an Action
like this:
class Main
{
public Main()
{
strClass str = new strClass(newString =>
{
console.log("This string I got back: " + newString);
});
}
}
class strClass
{
Action<string> callback;
public strClass (Action<string> callback)
{
// save the action
this.callback = callback;
}
public receiveData ( string str )
{
// Do something with the string
callback(str);
}
}
Upvotes: 2
Reputation: 8498
A delegate is a better option here.
class Main
{
public Main()
{
StrClass str = new StrClass(this.Handler);
}
public void Handler ( )
{
//called from recieve data
}
}
class StrClass
{
readonly Action _handler;
public StrClass ( Action callback)
{
// save the object
this._handler = callback;
}
public void receiveData( string str )
{
this._handler();
}
}
Upvotes: 4
Reputation: 1064134
Firstly, if you must call an unknown method by name, use dynamic
- it is heavily optimised for this (although still not a great idea):
((dynamic)handler).handler(); // but please don't use this! see below
However, I would instead look at either an Action<string>
(or maybe Func<string,string>
), or an interface with a known method on it.
Upvotes: 0
Reputation: 164
Even nicer than using delegates whould be using the Chain of Responsibility design pattern, which does exactly what you need :).
Upvotes: 0
Reputation: 15086
Couldn't you use interfaces instead:
interface IStringHandler {
void HandleString(string s);
}
class strClass
{
IStringHandler handler = null;
public strClass(IStringHandler handler)
{
this.handler = handler;
}
public void ReceiveData(string s)
{
handler.HandleString(s);
}
}
class Main : IStringHandler
{
// Your code
}
Upvotes: 5