无法将 List<List<int>> 转换为 return 类型 IList<IList<int>>
Unable to convert List<List<int>> to return type IList<IList<int>>
层序遍历为什么会出现这个异常?
发生以下异常:
Cannot implicitly convert type 'System.Collections.Generic.List<System.Collections.Generic.List<int>>
' to 'System.Collections.Generic.IList<System.Collections.Generic.IList<int>>
'. An explicit conversion exists (are you missing a cast?)
public IList<IList<int>> LevelOrder(TreeNode root)
{
var result = new List<List<int>>();
var que = new Queue<TreeNode>();
//if(root==null) return result;
que.Enqueue(root);
while(que.Count!=0)
{
int n = que.Count;
var subList = new List<int>();
for(int i=0;i<n;i++)
{
if(que.Peek().left!=null)
que.Enqueue(que.Peek().left);
if(que.Peek().right!=null)
que.Enqueue(que.Peek().right);
subList.Add(que.Dequeue().val);
}
result.Add(subList);
}
return result;
}
只需将结果声明更改为 List<IList<int>>
。
List<T>
实现了 IList<T>
,但是 List<List<T>>
没有实现 IList<IList<int>>
。除非以这种方式定义,否则泛型参数不是协变或逆变的,而 IList<T>
不是,因此类型必须完全匹配。
public IList<IList<int>> LevelOrder(TreeNode root)
{
var result = new List<IList<int>>();
var que = new Queue<TreeNode>();
//if(root==null) return result;
que.Enqueue(root);
while (que.Count != 0)
{
int n = que.Count;
var subList = new List<int>();
for (int i = 0; i < n; i++)
{
if (que.Peek().left != null)
que.Enqueue(que.Peek().left);
if (que.Peek().right != null)
que.Enqueue(que.Peek().right);
subList.Add(que.Dequeue().val);
}
result.Add(subList);
}
return result;
}
可以肯定的是,如果它可以编译,那么进行强制转换是一个非常糟糕的主意。原因如下:
public class myStupidList : IList<int>
{
//implementation unimportant
}
private void Button_Click(object sender, RoutedEventArgs e)
{
var result = new List<List<int>>();
IList<IList<int>> imNotAListofLists = (IList<IList<int>>)result;
imNotAListofLists.Add(new myStupidList());
//result is not a very valid variable right now, is it?
}
正如我在评论中提到的,这些类型的收集问题归结为 covariance
和 contravariance
,而 .NET 确实提供了很多工具来处理它们。 (比如各种只读集合和接口)
..这也解释了为什么您也会收到错误。没有从 List<List>
到 List<IList>
的隐式转换,因为如果不破坏类型安全,转换就无法成功。 (正如@Grax 提到的,两者都不是从另一个派生的)
应该是显式转换,如下图:-
List<IList<int>> result = new List<IList<int>>();
或
var result = new List<IList<int>>();
层序遍历为什么会出现这个异常? 发生以下异常:
Cannot implicitly convert type '
System.Collections.Generic.List<System.Collections.Generic.List<int>>
' to 'System.Collections.Generic.IList<System.Collections.Generic.IList<int>>
'. An explicit conversion exists (are you missing a cast?)
public IList<IList<int>> LevelOrder(TreeNode root)
{
var result = new List<List<int>>();
var que = new Queue<TreeNode>();
//if(root==null) return result;
que.Enqueue(root);
while(que.Count!=0)
{
int n = que.Count;
var subList = new List<int>();
for(int i=0;i<n;i++)
{
if(que.Peek().left!=null)
que.Enqueue(que.Peek().left);
if(que.Peek().right!=null)
que.Enqueue(que.Peek().right);
subList.Add(que.Dequeue().val);
}
result.Add(subList);
}
return result;
}
只需将结果声明更改为 List<IList<int>>
。
List<T>
实现了 IList<T>
,但是 List<List<T>>
没有实现 IList<IList<int>>
。除非以这种方式定义,否则泛型参数不是协变或逆变的,而 IList<T>
不是,因此类型必须完全匹配。
public IList<IList<int>> LevelOrder(TreeNode root)
{
var result = new List<IList<int>>();
var que = new Queue<TreeNode>();
//if(root==null) return result;
que.Enqueue(root);
while (que.Count != 0)
{
int n = que.Count;
var subList = new List<int>();
for (int i = 0; i < n; i++)
{
if (que.Peek().left != null)
que.Enqueue(que.Peek().left);
if (que.Peek().right != null)
que.Enqueue(que.Peek().right);
subList.Add(que.Dequeue().val);
}
result.Add(subList);
}
return result;
}
可以肯定的是,如果它可以编译,那么进行强制转换是一个非常糟糕的主意。原因如下:
public class myStupidList : IList<int>
{
//implementation unimportant
}
private void Button_Click(object sender, RoutedEventArgs e)
{
var result = new List<List<int>>();
IList<IList<int>> imNotAListofLists = (IList<IList<int>>)result;
imNotAListofLists.Add(new myStupidList());
//result is not a very valid variable right now, is it?
}
正如我在评论中提到的,这些类型的收集问题归结为 covariance
和 contravariance
,而 .NET 确实提供了很多工具来处理它们。 (比如各种只读集合和接口)
..这也解释了为什么您也会收到错误。没有从 List<List>
到 List<IList>
的隐式转换,因为如果不破坏类型安全,转换就无法成功。 (正如@Grax 提到的,两者都不是从另一个派生的)
应该是显式转换,如下图:-
List<IList<int>> result = new List<IList<int>>();
或
var result = new List<IList<int>>();