不能在c#中使用"内联"数组?

Fat*_*tie 83 c#

想象一下,你有这个地方

public static T AnyOne<T>(this T[] ra) where T:class
    {
    int k = ra.Length;
    int r = Random.Range(0,k);
    return ra[r];
    }
Run Code Online (Sandbox Code Playgroud)

甚至只是这个

public static string OneOf(this string[] strings)
    {
    return "a";
    }
Run Code Online (Sandbox Code Playgroud)

然后,当然你可以这样做......

string[] st = {"a","b","c"};
string letter = st.AnyOne();
Run Code Online (Sandbox Code Playgroud)

......这很棒.但.看起来你不能这样做:

string letter = {"a","b","c"}.AnyOne();
Run Code Online (Sandbox Code Playgroud)

或者也许是这个

string letter = ( {"a","b","c"} ).AnyOne();
Run Code Online (Sandbox Code Playgroud)

或者我试过的任何其他事情

事实上(1)为什么一个人不这样做?(2)我错过了什么,如果有办法,你会怎么做?

adr*_*dar 113

您必须首先使用创建阵列new[].

string letter = (new[] {"a","b","c"}).AnyOne();
Run Code Online (Sandbox Code Playgroud)

正如@hvd所提到的那样,你可以在没有parantheses的情况下做到这一点(..),我添加了parantheses因为我认为它更具可读性.

string letter = new[] {"a","b","c"}.AnyOne();
Run Code Online (Sandbox Code Playgroud)

并且您可以new string[]像其他答案一样指定数据类型.


您不能这样做{"a","b","c"},因为您可以将其视为填充数组的一种方式,而不是创建它.

另一个原因是编译器会混淆,不知道要创建什么,例如a string[]{ .. }或a List<string>{ .. }.

使用just new[]编译器可以通过数据类型(".."),之间{..},你想要的(string)知道.重要的是[],这意味着你想要一个数组.

你甚至不能创建一个空数组new[].

string[] array = new []{ }; // Error: No best type found for implicity-typed array
Run Code Online (Sandbox Code Playgroud)

  • 你不需要那些括号.`string letter = new [] {"a","b","c"}.AnyOne();`就好了.如果你想要它们,如果你认为它在括号中更具可读性,那么它们是有效的,但在这种情况下,我认为至少值得一提的是,它是你自觉的选择,它不是被语言强迫的. (13认同)

Hab*_*bib 50

(1)为什么一个人不这样做? {"a","b","c"}.AnyOne();

这一行:

string[] st = {"a","b","c"};
Run Code Online (Sandbox Code Playgroud)

是等效数组创建表达式的 简写(在ILSpy下)

string[] st = new string[]  {"a","b","c"};
Run Code Online (Sandbox Code Playgroud)

string[] st = {"a","b","c"} 只能在申报时使用,你不能在别处使用它,你甚至不能这样做:

string[] st;
st = {"a", "b", "c"}; //Error
Run Code Online (Sandbox Code Playgroud)

对于C#语言规范中的数组创建表达式,在第7.6.10.4节中进行了解释.

因此,"{"a", "b", "c"}"仅在声明中没有使用这意味着什么.因此,您不能将它与扩展方法一起使用,因为您的扩展方法在数组上运行.

(2)我错过了什么,如果有办法,你会怎么做?

已经在@ adricadar的回答中提到过,您可以这样做:

(new[] {"a","b","c"}).AnyOne();
Run Code Online (Sandbox Code Playgroud)

要么

(new string[] {"a","b","c"}).AnyOne();
Run Code Online (Sandbox Code Playgroud)


Eri*_*ert 44

我推回"为什么不"的问题,因为首先,答案几乎永远不会令人满意 - 你已经得到答案"这个功能不是你想要它的方式,因为规范没有说明你想要它说什么" ,我想这不是一个特别令人满意的答案.其次,设计团队没有必要证明为什么世界不是你想要的那样; 功能不是免费存在的,然后是用语言设计的; 相反,功能必须首先证明,然后设计.

因此,让我们试着让你的"为什么不"问题更加清晰.现有的特征是"在初始化时可以在等于右侧使用数组初始化器(a),或者在数组类型的对象构造右侧使用(b)." 提出的特征是:"数组初始化器也可以用作表达式".问题是"埃里克对拟议的特征会有什么批评?"

我要提出的第一个批评是,目前还不清楚表达的类型是什么.在变量初始值设定项中,您具有变量的类型,在对象创建表达式中,您具有对象的类型; 从这两个方面我们可以推导出构造数组的类型.没有提示,我们应该推断出什么类型?

在C#1.0中,当添加此功能时,在该语言中总共进行了零类型推断.C#早期的设计原则是"没有惊喜",编译器并不"太聪明".如果开发人员希望表达式具有特定类型,那么该类型在表达式中应该是显而易见的.当你说

new double[] { 1, 2, 3.4 }
Run Code Online (Sandbox Code Playgroud)

很清楚什么类型的意图.同样

new Animal[] { cat, dog, null }
Run Code Online (Sandbox Code Playgroud)

提议的功能违反了这一原则.表达式必须具有类型,但绝不清楚参数的类型是什么

M({cat, dog, null})
Run Code Online (Sandbox Code Playgroud)

而且:假设我们有两个重载M,其中一个采用数组,Animal一个采用数组IPet.哪种超载M适用?其中一个转换比另一个好吗?元素的类型是CatDog; 推断一种甚至不出现在那里的类型是否有意义?这些都是设计团队必须考虑的问题,而这些问题绝不是明显的答案.拟议的特征使我们在很短的时间内进入深水区.

现在,C#3.0解决了这个问题,因为C#3.0增加了许多功能,编译器代表开发人员推断了类型.关于"没有惊喜"和"简单规则"的早期原则与使LINQ工作所需的其他设计原则相冲突.您建议的功能是否已添加到C#3.0中?

它可能是.C#3.0中实际添加的功能是:

new[] { x, y, z }
Run Code Online (Sandbox Code Playgroud)

使用算法推断数组的类型:获取具有类型的元素的表达式,确定哪些类型是所有其他表达式可转换为的唯一最常规类型,如果存在这样的类型,请选择该类型.否则会产生错误,

可以进一步放宽该功能以使其成为new[]可选项.这没用.

现在,如果您在C#3.0时间框架中要求我批评建议的功能,我会指出(1)C#3.0编译器已经存在严重危害整个版本的时间表,所以让我们不再添加设计,实现和测试负担,完全不必要的功能,为用户节省了六次击键,(2)C#3.0还添加了集合初始化器:

new List<int>() { 10, 20, 30 }
Run Code Online (Sandbox Code Playgroud)

为什么要{10, 20, 30}自动成为一个数组?为什么不应该是一个List<int>?或者其他许多类型中的任何一种?为什么偏向阵列?请记住,一旦我们选择为数组提供语法,我们就会永远坚持下去.它可能永远不会是其他任何东西,因此提出的功能不仅是不必要的,它还可以防止可能的未来功能似乎是合理的.

总结:建议的功能直接违反了C#1.0的一些设计原则.它只为C#3.0增加了不必要的负担.在C#3.0以后的所有语言版本中,建议的功能没有任何好的理由来推荐花费时间,精力和金钱来支持许多其他更有价值的功能.

因此,没有这样的功能.

  • @JoeBlow:首先,你非常欢迎.关于"为什么不" - 您的评论很好地说明了问题.当有些人问"为什么"这个问题时,他们正在寻找合理的理由*.有些人正在寻找*务实的理由*.而且您显然正在寻找描述规则*的规范行.它是如此模糊,以至于很难找到一个很好的答案,这个答案主要针对提问者心中的问题."为什么不"问题更糟糕,因为它们是关于甚至不存在的事物的模糊问题*. (5认同)
  • @EricLippert这甚至比关于_might_存在的问题的问题更糟糕*:如果你正在与团队合作开发软件,整个团队每年都会花费时间考虑功能并平衡后果.作出决定.功能请求和'为什么'要求理由.然而,*为什么不*暗示某人只是想要完成某件事,这基本上质疑了团队本身的判断.更糟糕的是,询问*为什么不*问题的人通常对这个问题知之甚少.因此,我认为推迟*为什么不*问题是完全公平的.干得好IMO. (3认同)