空条件、空合并、可枚举和参数关键字

问题描述 投票:0回答:1

我不知道该为这个问题选择什么更好的标题,因为我不知道问题是什么。考虑以下简短的 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
c# ienumerable null-coalescing-operator null-conditional-operator params-keyword
1个回答
0
投票

您可能知道,对于

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[]

© www.soinside.com 2019 - 2024. All rights reserved.