F#强制加载System.String.Format

F#强制加载System.String.Format,f#,overloading,F#,Overloading,我想使用有5个重载的System.string.format格式化字符串: String String.Format(String format , Object arg0 ) String String.Format(String format , Object arg0 , Object arg1 ) String String.Format(String format , Object arg0 , Object arg1 , Object arg2 ) String String.For

我想使用有5个重载的
System.string.format
格式化字符串:

String String.Format(String format , Object arg0 )
String String.Format(String format , Object arg0 , Object arg1 )
String String.Format(String format , Object arg0 , Object arg1 , Object arg2 )
String String.Format(String format , params Object[] args )
String String.Format(IFormatProvider provider , String format , params Object[] args )
我想使用第四个重载(获取对象数组的重载),如下所示:

let frm = "{0} - {1}"
let args = [| 1; 2 |]
System.String.Format(frm, args)
问题是args参数被解释为对象,因此调用第一个重载。因此,我正确地得到了以下错误:

System.FormatException: Index (zero based) must be greater than or equal to zero and less than the size of the argument list.

有没有办法强制执行“正确”重载?

您可以通过将数组的每个元素切换到如下对象来强制执行正确的重载:

let frm = "{0} - {1}"
let args = [| 1:> obj; 2 :>obj|]
System.String.Format(frm, args);;
或者如果你有一个较长的列表

let frm = "{0} - {1}"
let args = [| 1; 2 |] |> Array.map (fun t ->t:> obj)
System.String.Format(frm, args);;

@John答案的一个更优雅的变体是添加类型注释,以便编译器对数组的所有元素进行自动向上转换:

let frm = "{0} - {1}"
let args : obj [] = [| 1; 2 |]
System.String.Format(frm, args)

对所以我应该把所有元素都转换成object?有没有理由不使用惯用的方法:
sprintf“%d-%d”12
-它就是为了避免这个问题而存在的?为什么要创建冗余数组而不是通过
String.Format(“{0}-{1}”,框1,框2)调用第二个重载?或者为什么不
sprintf“%A”[| 1;2 |]
?(我相信你有一个理由,但也没有坏处去弄清楚为什么这些途径不适合实现最好的答案)@JohnPalmer,你也可以做
Array.map box
,这也应该做同样的事情。我昨晚刚刚不得不这么做!