问题描述
|
据我所知,C#允许仅方法的最后一个参数为“可变长度”,例如:
T f(A a,params B[] b)
允许如果您有have1ѭ,您可以像f2ѭ一样调用f。为什么C#还没有定义如下内容:
T f(params A[] a,params B[] b)
解决方法
因为编译器将如何知道第一个参数的变量参数何时停止?
请告诉我方法主体中应包含
argOne
和argTwo
:
void Foo( params object[] argOne,params object[] argTwo )
{
// whatever
}
Foo( 1,false,\"Hello\",new object(),2.3 );
, 因为确定何时实际允许这种构造将太复杂。
(当通话是明确的时)
尽管可以创建一组良好的规则,但是它们将相当复杂且难以理解。人们最终会问,如果案例X含糊不清,为什么情况不起作用。
例如:
两种类型都不能是接口或通用参数
如果一种类型是枚举或数字类型,则另一种必须是除object
或Enum
以外的其他类
如果一种类型是委托类型,则另一种也不能同时是委托类型(既不是object
,Delegate
也不是MulticastDelegate
)
一种类型不能继承另一种
所有这些规则适用于隐式转换为参数类型的任何类型
两种类型都必须是“ 12”或必须是值类型
(其中一些规则可以在呼叫站点强制执行)
在实践中,这样的功能将有太多限制,以至于几乎一文不值。
因此,此功能将从-10,000点开始。
它还将创建一个全新的突破性变化类别。现在,打开类型,添加隐式转换或其他看似微不足道的操作可能会破坏客户端代码。
, 因为模棱两可。如果您去做:
T f(params int[] a,params int[] b)
然后您致电:
f(1,2,3,4)
编译器将如何知道一个从哪里开始而另一个从哪里开始呢?您可能会争辩说,这样的情况仍然可以标记为编译错误,并且仍然允许明确的情况继续进行,但是通过继承,情况可能会变得复杂,这是不值得的。而是传递两个数组。我想不出任何需要两个参数数组的情况,即使那样,它也是语法糖。两者之间没有什么区别,只是使用数组没有区别。
(另一个例子:
T f(params string[] a,params object[] b);
string
继承自object
。这仍然模棱两可...)
, 有许多极端情况使这成为不可能的功能。考虑以下示例:
public static class Coolifier
{
public static void BeCool<A,B>(params A[] a,params B[] b)
{
}
}
Coolifier.BeCool<string,string> (\"I\",\"don\'t\",\"work.\",\"DO\",\"I\",\"?\");
该示例说明了如何无法知道第一个params []的结束位置和下一个params的开始位置。
, 这会带来问题并导致冲突。
例如,假设ѭ19继承自ѭ20。
编译器将如何理解:
f(A1,A2,B1,B2)
是22英镑还是23英镑?
我认为理论上编译器可以很聪明,并且可以检测冲突。
但是,最初设计.NET和C#本身时,其想法是试图避免出现此类明确且棘手的情况。
, void DoSomething( params object[] p1,params int[] p2 )
{
...
}
DoSomething( 1,3 );
考虑编译器是否可以解决该问题。您可以对\'... \'部分进行编码吗?如果是,它可读吗?
我可以告诉你:那将是一团糟。
, 如果\'last parameter \'具有可变长度,则不必缠绕您的第二个/第三个/ n个参数,因为根据您的示例该参数将包含在第一个参数中,并且可能会模棱两可:
T f(params A[] a,params B[] b)
b将包含在a中