是否有更短的方法来创建IDictionary<_,obj>
,可能没有装箱每个值?这就是我所拥有的。
let values =
[ "a", box 1
"b", box "foo"
"c", box true ]
|> dict
Dictionary<_,obj>.Add
可以在没有拳击的情况下调用,但是我无法找到一种比我更短的方法来使用它。
我希望除了定义一个拳击操作员之外的东西。
根据Brian的建议,这是一种方法,但它有自己的问题。
let values =
Seq.zip ["a"; "b"; "c"] ([1; "foo"; true] : obj list) |> dict
答案 0 :(得分:10)
这是一个解决方案,遵循kvb的建议(可能是最简洁,最清晰,到目前为止):
let inline (=>) a b = a, box b
let values =
[ "a" => 1
"b" => "foo"
"c" => true ]
|> dict
答案 1 :(得分:3)
这是我能够掀起的最简单的事情。它有比拳击版更多的角色,但可能感觉不那么脏。请注意,^
是右关联的(它是从ocaml继承的字符串连接运算符),它使其像::
一样工作,并且它具有比,
更强的优先级,这就是为什么在元组周围需要括号。
let inline (^+) (x1:'a,x2:'b) (xl:('a*obj) list) =
(x1,box x2)::xl
let values =
("a", 1) ^+ ("b", "foo") ^+ ("c", true) ^+ []
|> dict
答案 2 :(得分:2)
我在FsSql中遇到了类似的问题,我只是在一个函数中隐藏拳击:
let inline T (a,b) = a, box b
let values = dict [T("a",1); T("b","foo"); T("c",true)]
答案 3 :(得分:2)
这是另一个“解决方案”,它受到Brian的建议的启发,但它使用反射,因此有时间和安全成本。
let unboxPair (pair:obj) =
let ty = pair.GetType()
let x = ty.GetProperty("Item1").GetValue(pair,null) :?> string
let y = ty.GetProperty("Item2").GetValue(pair,null)
x,y
let unboxPairs (pairs:obj list) =
pairs |> List.map unboxPair
let values =
unboxPairs
["a", 1
"b", "foo"
"c", true]
|> dict
答案 4 :(得分:1)
斯蒂芬的想法的变化:
open System
open System.Collections.Generic
type Dictionary<'a,'b> with
member this.Add([<ParamArray>] args:obj[]) =
match args.Length with
| n when n % 2 = 0 ->
for i in 1..2..(n-1) do
this.Add(unbox args.[i-1], unbox args.[i])
| _ -> invalidArg "args" "even number of elements required"
let d = Dictionary<string,obj>()
d.Add(
"a", 1,
"b", "foo",
"c", true
)
答案 5 :(得分:0)
另一种解决方案,只需在Dictionary<'a,'b>
上定义一堆重载的扩展成员:
open System.Collections.Generic
type Dictionary<'a,'b> with
member this.Add(x1,y1,x2,y2) =
this.Add(x1,y1)
this.Add(x2,y2)
member this.Add(x1,y1,x2,y2,x3,y3) =
this.Add(x1,y1,x2,y2)
this.Add(x3,y3)
member this.Add(x1,y1,x2,y2,x3,y3,x4,y4) =
this.Add(x1,y1,x2,y2,x3,y3)
this.Add(x4,y4)
member this.Add(x1,y1,x2,y2,x3,y3,x4,y4,x5,y5) =
this.Add(x1,y1,x2,y2,x3,y3,x4,y4)
this.Add(x5,y5)
member this.Add(x1,y1,x2,y2,x3,y3,x4,y4,x5,y5,x6,y6) =
this.Add(x1,y1,x2,y2,x3,y3,x4,y4,x5,y5)
this.Add(x6,y6)
//etc.
let values =
let d = Dictionary<_,obj>()
d.Add("a", 1,
"b", "foo",
"c", true)
d
当然values
这里的不不可变,就像你的问题一样,但我相信你可以在这个目标中采用相同的策略。
答案 6 :(得分:-1)
let v : (string*obj) list = [...]
let values = dict v
单向,列表文字左侧的类型签名将自动向上转换每个元素。