[英]Inconsistent processing of generic ParamArray argument in F#
Being spotted in context of this question this seemingly inconsistent behavior can be reproduced as following both in F#2.0 and F#3.0 RC: 在这个问题的背景下被发现这个看似不一致的行为可以在F#2.0和F#3.0 RC中重现:
type Heterogeneous =
static member Echo([<ParamArray>] args: Object[]) = args
type Generic =
static member Echo<'T>([<ParamArray>] args: 'T[]) = args
Usage: Returns: 用法:返回:
Heterogeneous.Echo 0 // [|0|] OK
Generic.Echo 0 // [|0|] OK
Heterogeneous.Echo (0,1) // [|0; 1|] OK
Generic.Echo (0,1) // [|0; 1|] OK
Heterogeneous.Echo [|0|] // [|[|0|]|] OK?
Generic.Echo [|0|] // [|0|] OOPS!!
Heterogeneous.Echo ([|0|],[|1|])) // [|[|0|]; [|1|]|] OK
Generic.Echo ([|0|],[|1|])) // [|[|0|]; [|1|]|] OK
Can anyone explain if the observed behavior is a bug, or feature? 任何人都可以解释观察到的行为是否是一个错误或功能?
UPDATE: This related answer communicates a confirmation from F# development team that as of now a bug has place in processing of generic type arguments with ParamArray
attribute. 更新:这个相关的答案传达了F#开发团队的确认,到目前为止,在使用
ParamArray
属性处理泛型类型参数时存在一个错误。
The case is slightly confusing because when you use an array as an actual argument to a parameter marked with ParamArray
, the language tries to interpret it as if you were passing array to a normal array-typed parameter (so it ignores the ParamArray
attribute if possible). 这种情况有点令人困惑,因为当您使用数组作为标记有
ParamArray
的参数的实际参数时,该语言会尝试将其解释为将数组传递给普通的数组类型参数(因此如果可能,它会忽略ParamArray
属性) )。
In your example, this is possible in the second case: 在您的示例中,在第二种情况下可以这样做:
Generic.Echo [|0|]
The compiler infers that 'T
is int
and so you're passing int[]
to a parameter of type int[]
and so the compiler ignores ParamArray
attribute and the method simply gets an array containing 0
. 编译器推断
'T
是int
等你传递int[]
到类型的参数int[]
因此编译器会忽略ParamArray
属性和方法只是获取包含数组0
。
In the other case, this is not possible: 在另一种情况下,这是不可能的:
Heterogeneous.Echo [|0|]
The method expects a parameter of type obj[]
and the type of the argument is int[]
, so the two types cannot be unified (the key is that the compiler does not automatically convert int[]
to obj[]
). 该方法需要一个
obj[]
类型的参数,并且参数的类型是int[]
,因此这两种类型不能统一(关键是编译器不会自动将int[]
转换为obj[]
)。 Since this is not possible, it considers the ParamArray
attribute and tries to convert int[]
to obj
and pass it as a member of ParamArray
- this is a conversion that the compiler can automatically perform and so you get the result you described. 由于这是不可能的,它会考虑
ParamArray
属性并尝试将int[]
转换为obj
并将其作为ParamArray
的成员传递 - 这是编译器可以自动执行的转换,因此您可以获得所描述的结果。
If you called Heterogeneous.Echo
with obj[]
as an argument, then it would behave similarly to Generic.Echo
. 如果您使用
obj[]
作为参数调用Heterogeneous.Echo
,那么它的行为与Generic.Echo
类似。 For example: 例如:
Heterogeneous.Echo [| box 0 |]
If you want to go into details, you can look at section 14.4. 如果您想了解详细信息,请参阅第14.4节。 of the F# language specification .
F#语言规范 。 However, the overload resolution rules are pretty complex and so I don't have an exact reference that explains this behaviour - just an informal explanation above.
但是,重载决策规则非常复杂,所以我没有一个解释这种行为的确切参考 - 只是上面的非正式解释。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.