我不知道该为这个问题选择什么更好的标题,因为我不知道问题是什么。考虑以下简短的 C# 代码:
static void Main(string[] args)
{
F1(null);
}
public static void F1(int[] values)
{
F2(1, values?[0] as object ?? new object[0]);
F2(2, values?.Select(v => (object)v) ?? new object[0]);
F2(3, values?.Select(v => (object)v).ToArray() ?? new object[0]);
}
public static void F2(int idx, params object[] values)
{
Console.WriteLine($"count {idx}: '{values?.Count()}'");
}
它输出:
count 1: '1'
count 2: '1'
count 3: '0'
为什么前2个是1?如果我在 Visual Studio 中使用立即窗口,则以下所有内容均为空:
values?[0]
null
values?.Select(v => (object)v)
null
values?.Select(v => (object)v).ToArray()
null
您可能知道,对于
params
类型的 object[]
参数,您可以传递 object
类型的表达式(这会隐式创建 object[]
并且您传递的 object
将被视为元素数组的),或 object[]
类型的表达式(将“直接”传递给方法)。
object[] x = new object[0];
object y = new object();
F2(1, x); // values?.Count() is 0
F2(2, y); // values?.Count() is 1
值得注意的是,这仅取决于表达式的编译时类型(除非有
dynamic
的事情发生)。因此,类型为 object
的表达式将被包装在数组中,即使该表达式在运行时计算结果为 object[]
对象。
object z = new object[0];
F2(3, z); // values?.Count() is 1
考虑到这一点,就应该清楚为什么你的代码会有这样的行为。这两个表达式的类型都是
object
:
values?[0] as object ?? new object[0]
values?.Select(v => (object)v) ?? new object[0]
values?[0] as object
属于 object
类型,values?.Select(v => (object)v)
属于 IEnumerable<object>
类型。但 ??
的右侧是 object[]
类型。所以在这两种情况下整个表达式都是 object
类型。
如果
values?.Select(v => (object)v).ToArray() ?? new object[0]
values?.Select(v => (object)v).ToArray()
的类型为 object[]
,与 new object[0]
类型相同,因此整个表达式的类型为 object[]
。