I’m creating a generic interface to work as command pattern:
public interface IGenericComponent<T> where T : IVisitableObject
{
void Update(T msg);
}
Then, I’ll have another class that I’ll hold a bunch of implementations of this interface (each one with its own type). There I would have a dictionary to put the list of commands to execute like this:
private Dictionary<MessageType, List<IGenericComponent>> _components;
This generates a compilation error because I don’t put the type for the IGenericComponent. I have a thread that calls the Update method and a method to subscribe (inserta an component to the dictionary):
public void Subscribe<T>(MessageType messageType, IGenericComponent<T> component) where T : IVisitableObject, new()
{
lock (_monitorDictionary)
{
List<IGenericComponent> subscribedList;
if (_components.TryGetValue(messageType, out subscribedList))
{
subscribedList.Add(component);
IVisitableObject firstUpdate;
if(_messageBuffer.TryGetValue(messageType, out firstUpdate))
component.Update((T)firstUpdate);
}
else
{
subscribedList = new List<IGenericComponent>();
subscribedList.Add(component);
_components[messageType] = subscribedList;
}
}
}
private void ProcessQueue()
{
while (true)
{
IVisitableObject msg;
lock (_monitorQueue)
{
msg = _queue.Dequeue();
}
List<IGenericComponent> components;
lock(_monitorDictionary)
{
components = _components[msg.MsgType];
}
if(components!= null)
{
foreach (IGenericComponent genericComponent in components)
genericComponent.Update(msg);
}
}
}
This code does not compile…
I came from Java programming, and in Java I can ommit the parametrized type when I instantiate the type. So… I would like to know if is it possible to do that in C# so it would assume that its the generic type (IVisitableObject). Or if you know a better way to solve this problem…
The way I’ve solved this is not the way I would like to use. I’ve removed generics from the interface and used the generic type IVisitableObject as the parameter of Update method.
Thanks in advance.
I’ve used the approach in Jason’s answer and it works fine, especially if you can hide the cast from
IVisitableObjecttoTin a base class. But if you want to avoid forcing classes to implement the non-generic interface, you can use this pattern. Store your subscribers as aList<object>and use a helper class (Dispatcher) to send the message.