我试图理解为什么以下代码中的隐式转换会导致StackOverflowException
。我认为这是一个协方差/逆变问题,但我现在无法解释为什么。
崩溃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);
}
使用:
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);
}
据我所知,回答https://stackoverflow.com/a/275107/761755应该隐式执行转换。
此外,如果在第一个示例中,您直接从_NodesContent.AddRange(nodes)
致电AddNodes(T[][])
,则不会有例外情况。
答案 0 :(得分:1)
我试图在下面的代码中理解为什么隐式转换 导致StackOverflowException。
嗯,没有必要进行隐式转换。但是不是很明显吗?您的第一个方法调用自身,因为您按原样传递参数:
public UnrolledLinkedListBuilder<T> AddNodes(params T[][] nodes)
{
return AddNodes(nodes);
}
如果在任何情况下都不会导致StackOverflowException
,那么这是一个编译错误:
public SomeReturnType AnyMethod(AnyType x)
{
return AnyMethod(x); // StackOverflowException
}
参数使用params
并不重要,因为没有params
的同一参数类型的另一种方法是不可能的,因为这是不明确的。所以这永远是最好的候选人。