Reputation: 629
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.
Upvotes: 0
Views: 323
Reputation: 460058
I'm trying to understand why implicit conversion in the following code causes StackOverflowException.
Well, there is no implicit conversion necessary. But isn't it obvious? Your first method calls itself because you pass the argument as it is:
public UnrolledLinkedListBuilder<T> AddNodes(params T[][] nodes)
{
return AddNodes(nodes);
}
It was a compiler bug if that would not cause a StackOverflowException
in any case:
public SomeReturnType AnyMethod(AnyType x)
{
return AnyMethod(x); // StackOverflowException
}
It doesn't matter that the parameter is using params
because it's not possible to have another method with the same parameter type without params
because that was ambiguous. So this will always be the best candidate.
Upvotes: 1