在下面的代码片段中,我的目的是将System.Object(可以是FSharpList)转换为它所持有的任何泛型类型的列表.
match o with
| :? list<_> -> addChildList(o :?> list<_>)
| _ -> addChild(o)
Run Code Online (Sandbox Code Playgroud)
不幸的是,只有list<obj>匹配列表.我也想list<Foo>作为一个列表进行匹配.
对于某些上下文,我试图通过反射遍历对象结构,以便构建类及其子类的TreeView.考虑以下课程:
type Entity = {
Transform : Matrix
Components : obj list
Children : Entity list
}
Run Code Online (Sandbox Code Playgroud)
我想构建一个树,向我展示实体中包含的所有类.通过反射,我可以获得对象的所有属性及其值(值很重要,因为我想在列表中显示元素的Name属性,如果有的话):
let o = propertyInfo.GetValue(obj, null)
Run Code Online (Sandbox Code Playgroud)
此值可能是某种类型的列表,但值返回只是一个System.Object我在尝试将此对象转换为列表时遇到问题.我被迫做以下事情:
match o with
| :? list<obj> -> addChildList(o :?> list<obj>)
| :? list<Entity> -> addChildList(o :?> list<Entity>)
| _ -> addChild(o)
Run Code Online (Sandbox Code Playgroud)
在这里,我必须准确指定我要转换为的类型.
我真的想写这个:
match o with
| :? list<_> -> addChildList(o :?> list<_>)
| _ -> …Run Code Online (Sandbox Code Playgroud) let f (O: obj) =
match O with
| :? (obj -> list<obj>) -> "win"
| :? list<obj> -> "list!"
| _ -> "fail"
Console.WriteLine(f(fun x -> ["lol"]))
Console.WriteLine(f(["lol"]))
Run Code Online (Sandbox Code Playgroud)
打印"失败"两次,因为我认为它应该,因为我给obj -> list<String>了一个功能,这不是一个obj -> list<obj>.有什么方法可以让它们匹配吗?我可以将每个列表上传到一个list<obj>之前,obj然后在它之前创建一个匿名函数,或者我可以将所有内容放到列表中.
这些都是有效的,并使它匹配,但我认为这是协方差/逆变已经解决的问题?如果我错了,请纠正我