Edit
What you are looking for is, as Daniel said, covariance.
If you use C # 4, it really exists, but not in a useful way for you. For this example to work, ICommandHandler must be contravariant. If TCommand was always an out parameter in ICommandHandler , and you would define ICommandHandler as
interface ICommandHandler<out TCommand> where TCommand: ICommand { ... }
then you can save ICommandHandler<TCommand> to List<ICommandHandler<ICommand>> , because ICommandHandler<TCommand> can be safely assigned to ICommandHandler<ICommand> - we know that if TCommand returns TCommand , it returns ICommand .
However, in your case, TCommand is an in parameter and to convert ICommandHandler<TCommand> to ICommandHandler<ICommand> you need to know that each ICommand is TCommand , which is obviously not true, so you cannot do this conversion.
None of the two solutions that I now think of is enough.
Make an untyped dictionary (a IDictionary<Type, IList> or even IDictionary<Type, object> ) and add to IList<ICommandHandler<TCommand>> , which will always work because you add only a command to it when the type matches.
Make an ICommandHandlerWrapper that accepts ICommandHandler<TCommand> as is ICommandHandler<ICommand> ; when a method is called, it performs a type check and calls the base value.
Old version

Perhaps your code example is missing something important.
But I want to ask why use
public void AddListItem<T>(T listItem) where T : IListItem { _items.Add(listItem); }
but not
public void AddListItem(IListItem listItem) { _items.Add(listItem); }
source share