Sure, good interface design can ease things, but it doesn't really solve the problem I'm talking about.
In Java, List<Foo> and List<Bar> are the same interface. In C#, IList<Foo> and IList<Bar> are different interfaces that just happen to have similar properties/methods.
Right, but again, it means you're implementing two separate interfaces. You can implement IList without implementing IList<T>, and you can implement IList<T> without implementing IList.
In Java, List<Foo> and List<Bar> are the same interface. In C#, IList<Foo> and IList<Bar> are different interfaces that just happen to have similar properties/methods.
This means, in Java you can do
Whereas, in C#, to do something similar, you have to dynamically compile at runtime a specialization of a generic delegate.