I'm trying to understand why implicit conversion in the following code causes StackOverflowException. I think it is a covariance/contravariance issue, but I cannot explain why at the moment.
Crashes NUnit:
private List<T[]> _NodesContent = new List<T[]>(); private UnrolledLinkedListBuilder<T> AddNodes(IEnumerable<T[]> nodes) { _NodesContent.AddRange(nodes); return this; } public UnrolledLinkedListBuilder<T> AddNodes(params T[][] nodes) { return AddNodes(nodes); } Works:
private List<T[]> _NodesContent = new List<T[]>(); private UnrolledLinkedListBuilder<T> AddNodes(IEnumerable<T[]> nodes) { _NodesContent.AddRange(nodes); return this; } public UnrolledLinkedListBuilder<T> AddNodes(params T[][] nodes) { return AddNodes((IEnumerable<T[])nodes); } As I understand from this answer https://stackoverflow.com/a/275107/761755 conversion should be performed implicitly. Moreover, if in the first example you directly call _NodesContent.AddRange(nodes) from AddNodes(T[][]) there will be no exception.
AddNodespassingT[][]- best fitting overload is of course one that acceptsT[][], not one that acceptsIEnumerable<T[]>. It doesn't matter if it's possible to convertT[][]toIEnumerable<T[]>or not.StackOverflowException? You are passing the argument directly to the method in which you are. It would be a compiler bug if you would call a different method (overload) then.nodesis aT[][]. There is a method overload that takes aT[][]as parameter, so that one will be chosen, resulting in a stack overflow.