C#中的语法不一致?

7
private string[] GetRoles()
{
    string[] foo = {"Test"};
    return foo;       
}

上述代码可以编译,但是......
private string[] GetRoles()
{
    return {"Test"};        
}

不行。

替换为:

return new string[] { "Test" };    

显然,它会编译通过。这是不一致的吗?还是我太蠢了,或者我错了:S。

4
请注意,由于类型推断,return new [] { "Test" }; 也可以正常工作。 - Benjamin Podszun
@Sander:“这是不一致吗”,尽管他忘了问号。 - AaronLS
5个回答

5

归功于@Luke:

第一个示例只是简写数组初始化语法。第二个示例根本不是合法的C#语法。


不正确。第一个示例中没有隐式转换:它只是简写的数组初始化语法。第二个示例不返回 object[]:它根本不是合法的 C# 语法。 - LukeH
你是不正确的,数组初始化器在返回语句中是不允许的。 - CodeRipper
2
@Luke,感谢你澄清这个问题。我在回答时手头没有编译器。但很高兴看到我错误的答案得到了很多赞。 - Klaus Byskov Pedersen

3
数组对象必须在返回值之前创建。因此,
return new string[]{"Test"};

给出正确的返回类型。


和其他人一样,问题在于可以省略operator new运算符。在将其赋值给变量之前,您需要创建一个对象,这里没有任何区别。 - CodeRipper

2

您的代码片段之所以不起作用,与下面的代码不能正常工作(即无法编译)的原因相同。

private string[] GetRoles()
{
    //string[] foo = {"Test"};
    var foo = {"Test"};
    return foo;       
}

在您的第一个片段中,string[] 提供了足够的信息给编译器,使得这个语法糖可以正常工作。

你正在展示未指定类型的类型推断。但是在 'return {"Test"};' 的情况下,必要的类型信息是方法的返回类型。没有任何阻止编译器找出它的方法。 - CodeRipper

1

历史上,您必须编写new运算符。像这样:

string[] foo = new string[] {"Test"};

我认为在C# 2.0中,可以省略new运算符,直接写:

string[] foo = {"Test"};

编译器可以确定您正在初始化数组的位置。我认为我同意您的看法,这是一种不一致性。当添加省略new运算符的可能性时,他们可能忘记了返回语句,因为很少返回在返回语句中初始化的数组。因为当编译器查看返回类型时,它应该能够像赋值的情况一样找出来。

个人而言,我从不省略new运算符,所以我甚至从未考虑过这个问题 :)


0
private string[] GetRoles()
{
    string[] foo = {"Test"};
    return foo;       
}

在上面的例子中,您正在创建一个新的string[]数组,然后用一个名为“Test”的元素进行初始化。
private string[] GetRoles()
{
    return {"Test"};        
}

在这个例子中,您创建了一个期望返回字符串数组的方法。然而,在任何时候都没有创建一个新的string array[]*对象。在您添加元素到数组之前,需要先创建它。您基本上是试图从不存在的数组返回元素,这就是为什么它失败的原因。
您可以认为编译器可以为您创建数组,但它在您的第一个示例中并没有这样做,那么为什么要期望它在第二个示例中这样做呢?

在你的第一个例子中,你没有创建数组并初始化。string[] foo只是创建了指向string[]的指针,仅此而已。C#规范允许省略new运算符,因此该行实际上读作string[] foo = new string[] {"Test"};。关键是为什么他们不允许在返回语句中省略new运算符,当类型信息以返回类型的形式预设时。 - CodeRipper
在第一个例子中,数组被初始化为一个值。你是说 "test" 没有被赋值吗? - Dan Diplo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接