Let's say I want to store delegates in a collection like this:
public void AddDelegate<T>(Action<T> action) where T : ISomething
{
_delegates.Add(action);
}
What should the type of _delegates be?
Trying with IList<Action<ISomething>> _delegates;
results in error message Argument type 'System.Action<T>' is not assignable to parameter type 'System.Action<ISomething>' for the Add call above. But why doesn't it work? The compiler should 'know' that T must be an ISomething.
What are my options if I don't want to loose type safety by using e.g. a IList<object> or parameterize the whole class on the generic type T?
_delegates has to be of type IList<Action<T>>.
Therefore you have to add the <T> where T : ISomething to the class.
Alternatively, do away with the generics and support Action<ISomething> directly.
So your two options are:
public class Delegates<T> where T : ISomething
{
private List<Action<T>> _delegates;
public void AddDelegate(Action<T> action)
{
_delegates.Add(action);
}
}
Or
public class Delegates
{
private List<Action<ISomething>> _delegates;
public void AddDelegate(Action<ISomething> action)
{
_delegates.Add(action);
}
}
Edit
As Sehnsucht points out, there's a third option: wrap the Action<T> delegate inside an Action<ISomething> delegate and then the OP can achieve what he originally wanted.
The reason for this is that whilst T is a "subtype" (implementer) of ISomething, Action<T> is not a subtype of Action<ISomething>, in fact as dcastro explains in his answer, the opposite is actually true (despite that seeming counter-intuitive). Even with casting, you cannot add an instance of Action<T> to a list of Action<ISomething>.
you should see here for more insight to the problem
I can propose that "kind of hack" to circumvent the problem but I can't say if it's a good thing or really just a hack.
void Add<T> (Action<T> action) where T : ISomething
{
Action<ISomething> typedAction = something => action ((T) something);
_delegates.Add (typedAction);
}
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