I've got the following class:
public class Terminal : IDisposable
{
readonly List<IListener> _listeners;
public Terminal(IEnumerable<IListener> listeners)
{
_listeners = new List<IListener>(listeners);
}
public void Subscribe(ref Action<string> source)
{
source += Broadcast;
//Store the reference somehow?
}
void Broadcast(string message)
{
foreach (var listener in _listeners) listener.Listen(message);
}
public void Dispose()
{
//Unsubscribe from all the stored sources?
}
}
I've searched for a while and it appears that an argument passed with the ref keyword can't be stored. Trying to add the source argument to a list or to assign it to a field variable doesn't allow it to keep a reference to the actual delegate's original reference; so my questions are:
Thank you.
EDIT: It appears that without using a Wrapper or Reflection, there's no solution to the given problem. My intention was to make the class as much portable as possible, without having to wrap delegates in helper classes. Thanks everyone for the contributions.
C# does not pass by reference unless you specify the ref keyword. However, since the value of a variable of a delegate type is a reference to a method, the value passed is a reference. Use the ref keyword and you pass a reference to the variable's store, not the method, thus it becomes possible to change its value.
A delegate is a type that represents references to methods with a particular parameter list and return type. When you instantiate a delegate, you can associate its instance with any method with a compatible signature and return type. You can invoke (or call) the method through the delegate instance.
When the return type is not void as above in my case it is int. Methods with Int return types are added to the delegate instance and will be executed as per the addition sequence but the variable that is holding the return type value will have the value return from the method that is executed at the end.
Edit: Ok, that was a bad idea, so back to the basics:
I recommend creating a wrapper class over an Action:
class ActionWrapper
{
public Action<string> Action;
}
And restructuring your initial class to work with wrappers:
private ActionWrapper localSource;
public void Subscribe(ActionWrapper source)
{
source.Action += Broadcast;
localSource = source;
}
public void Dispose()
{
localSource.Action -= Broadcast;
}
Now you should get the desired results.
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