想象一下,你有这个地方
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)
Hab*_*bib 50
(1)为什么一个人不这样做?
{"a","b","c"}.AnyOne();
这一行:
string[] st = {"a","b","c"};
Run Code Online (Sandbox Code Playgroud)
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
适用?其中一个转换比另一个好吗?元素的类型是Cat
和Dog
; 推断一种甚至不出现在那里的类型是否有意义?这些都是设计团队必须考虑的问题,而这些问题绝不是明显的答案.拟议的特征使我们在很短的时间内进入深水区.
现在,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以后的所有语言版本中,建议的功能没有任何好的理由来推荐花费时间,精力和金钱来支持许多其他更有价值的功能.
因此,没有这样的功能.
归档时间: |
|
查看次数: |
18565 次 |
最近记录: |