尝试将 `Concat` 与 `as` 一起使用时如何理解此 `System.ArgumentNullException`
How to understand this `System.ArgumentNullException` when trying to use `Concat` with `as`
我正在尝试解决 Leetcode 问题 二叉树前序遍历。以下是我到目前为止所写的内容:
using System.Collections.Generic;
using System.Linq;
public class TreeNode
{
public int val;
public TreeNode left;
public TreeNode right;
public TreeNode(int x) { val = x; }
}
public class Solution
{
public IList<int> PreorderTraversal(TreeNode root)
{
if (root == null)
{
return new List<int> { };
}
else
{
IList<int> ret = new List<int> { root.val };
ret = ret.Concat(PreorderTraversal(root.left)) as IList<int>;
ret = ret.Concat(PreorderTraversal(root.right)) as IList<int>;// <-- this line
return ret;
}
}
}
class Program
{
static void Main(string[] args)
{
var root = new TreeNode(42);
root.right = new TreeNode(99);
var result = new Solution().PreorderTraversal(root);
}
}
我用 ToList()
尝试了相同的算法,它成功了。但是当运行这段代码的时候,System.ArgumentNullException
在我标记的那一行被抛出。所以我的问题是它是从哪里来的?怎么理解呢?如何解决?
尽管 ret
的初始值是 IList<int>
,但使用 .Concat
时 return 类型是 IEnumerable<int>
。但是,您使用安全 (as
) 强制转换回 IList<Int>
;这不是有效的转换,因此您的第一个 .Concat
操作 return 为空...然后下一行尝试对空值进行操作。
.Concat
被实现为一个扩展方法,它将源(在本例中为 ret
)作为参数,因此当传递 null 时它会抛出一个 ArgumentNullException
。
您可以通过使用 IEnumerable<int>
作为 return 类型和 ret
的声明并删除您的转换来解决此问题。
using System.Collections.Generic;
using System.Linq;
public class TreeNode
{
public int val;
public TreeNode left;
public TreeNode right;
public TreeNode(int x) { val = x; }
}
public class Solution
{
public IEnumerable<int> PreorderTraversal(TreeNode root)
{
if (root == null)
{
return Enumerable.Empty<int>();
}
else
{
IEnumerable<int> ret = new List<int> { root.val };
ret = ret.Concat(PreorderTraversal(root.left));
ret = ret.Concat(PreorderTraversal(root.right));
return ret;
}
}
}
class Program
{
static void Main(string[] args)
{
var root = new TreeNode(42);
root.right = new TreeNode(99);
var result = new Solution().PreorderTraversal(root);
}
}
我正在尝试解决 Leetcode 问题 二叉树前序遍历。以下是我到目前为止所写的内容:
using System.Collections.Generic;
using System.Linq;
public class TreeNode
{
public int val;
public TreeNode left;
public TreeNode right;
public TreeNode(int x) { val = x; }
}
public class Solution
{
public IList<int> PreorderTraversal(TreeNode root)
{
if (root == null)
{
return new List<int> { };
}
else
{
IList<int> ret = new List<int> { root.val };
ret = ret.Concat(PreorderTraversal(root.left)) as IList<int>;
ret = ret.Concat(PreorderTraversal(root.right)) as IList<int>;// <-- this line
return ret;
}
}
}
class Program
{
static void Main(string[] args)
{
var root = new TreeNode(42);
root.right = new TreeNode(99);
var result = new Solution().PreorderTraversal(root);
}
}
我用 ToList()
尝试了相同的算法,它成功了。但是当运行这段代码的时候,System.ArgumentNullException
在我标记的那一行被抛出。所以我的问题是它是从哪里来的?怎么理解呢?如何解决?
尽管 ret
的初始值是 IList<int>
,但使用 .Concat
时 return 类型是 IEnumerable<int>
。但是,您使用安全 (as
) 强制转换回 IList<Int>
;这不是有效的转换,因此您的第一个 .Concat
操作 return 为空...然后下一行尝试对空值进行操作。
.Concat
被实现为一个扩展方法,它将源(在本例中为 ret
)作为参数,因此当传递 null 时它会抛出一个 ArgumentNullException
。
您可以通过使用 IEnumerable<int>
作为 return 类型和 ret
的声明并删除您的转换来解决此问题。
using System.Collections.Generic;
using System.Linq;
public class TreeNode
{
public int val;
public TreeNode left;
public TreeNode right;
public TreeNode(int x) { val = x; }
}
public class Solution
{
public IEnumerable<int> PreorderTraversal(TreeNode root)
{
if (root == null)
{
return Enumerable.Empty<int>();
}
else
{
IEnumerable<int> ret = new List<int> { root.val };
ret = ret.Concat(PreorderTraversal(root.left));
ret = ret.Concat(PreorderTraversal(root.right));
return ret;
}
}
}
class Program
{
static void Main(string[] args)
{
var root = new TreeNode(42);
root.right = new TreeNode(99);
var result = new Solution().PreorderTraversal(root);
}
}