如何在 F# 中将对象转换为泛型类型列表

2024-05-05

在下面的代码片段中,我的目的是将 System.Object(可能是 FSharpList)转换为它所持有的任何泛型类型的列表。

    match o with
    | :? list<_>              -> addChildList(o :?> list<_>)
    | _                       -> addChild(o)

不幸的是只有list<obj>曾经作为列表进行匹配。我想list<Foo>也可以作为列表进行匹配。

对于某些上下文,我尝试通过反射遍历对象结构,以便构建该类及其子级的 TreeView。考虑下面的类:

type Entity = {
    Transform   : Matrix
    Components  : obj list
    Children    : Entity list
}

我想构建一棵树来显示实体中包含的所有类。 通过反射,我可以获得对象的所有属性及其值(该值很重要,因为我想使用该元素的 Name 属性(如果有)显示列表中的不同元素):

        let o = propertyInfo.GetValue(obj, null)

该值可以是某种类型的列表,但返回的值只是一个 System.Object 尝试将此对象转换为列表时遇到问题。我被迫执行以下操作:

        match o with
        | :? list<obj>              -> addChildList(o :?> list<obj>)
        | :? list<Entity>           -> addChildList(o :?> list<Entity>)
        | _                         -> addChild(o)

在这里我必须准确指定我要转换的类型。
我真的很想写这个:

        match o with
        | :? list<_>              -> addChildList(o :?> list<_>)
        | _                       -> addChild(o)

不幸的是,这只匹配list< obj >


不幸的是,没有简单的方法可以做你想做的事。类型测试只能用于特定类型,即使类型测试通过,转换运算符:?>也只能将表达式转换为特定类型,因此匹配的右侧无论如何都不会执行您想要的操作。您可以使用活动模式部分解决此问题:

open Microsoft.FSharp.Quotations
open Microsoft.FSharp.Quotations.Patterns

let ( |GenericType|_| ) =
  (* methodinfo for typedefof<_> *)
  let tdo = 
    let (Call(None,t,[])) = <@ typedefof<_> @>
    t.GetGenericMethodDefinition()
  (* match type t against generic def g *)
  let rec tymatch t (g:Type) =
    if t = typeof<obj> then None
    elif g.IsInterface then
      let ints = if t.IsInterface then [|t|] else t.GetInterfaces()
      ints |> Seq.tryPick (fun t -> if (t.GetGenericTypeDefinition() = g) then Some(t.GetGenericArguments()) else None)
    elif t.IsGenericType && t.GetGenericTypeDefinition() = g then
      Some(t.GetGenericArguments())
    else
      tymatch (t.BaseType) g
  fun (e:Expr<Type>) (t:Type) ->
    match e with
    | Call(None,mi,[]) ->
        if (mi.GetGenericMethodDefinition() = tdo) then
          let [|ty|] = mi.GetGenericArguments()
          if ty.IsGenericType then
            let tydef = ty.GetGenericTypeDefinition()
            tymatch t tydef
          else None
        else
          None
    | _ -> None

该活动模式可按如下方式使用:

match o.GetType() with
| GenericType <@ typedefof<list<_>> @> [|t|] -> addChildListUntyped(t,o)
| _                                          -> addChild(o)

你创建了一个变体addChildList它需要一个类型t和一个物体o(运行时类型list<t>)而不是采用通用列表。

这有点笨拙,但我想不出更干净的解决方案。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 F# 中将对象转换为泛型类型列表 的相关文章

  • F# 会自动内联一些函数,即使它们没有标记为“inline”,这是有意的吗?

    看起来 F 会自动内联一些函数 即使它们没有标记为 内联 let a x x 3 let b x x x let funB x y if x gt y then 3 else 1 let funC x let s a x let c fun
  • 按相反顺序对列表进行排序

    我有直接顺序的列表 list1 List
  • 在 Java 8 中使用映射函数时类型转换不起作用

    我正在比较两个列表 List allUserGroups UserBC getAllGroupsForUser userId deptID List
  • 列表 到数据视图

    如何在 Net 中将列表转换为数据视图 我的建议是将列表转换为 DataTable 然后使用表的默认视图来构建 DataView 首先 您必须构建数据表
  • 将不均匀的层次列表转换为数据框

    我认为还没有有人问过这个问题 但是有没有一种方法可以将具有多个级别和不均匀结构的列表的信息组合成 长 格式的数据帧 具体来说 library XML library plyr xml inning lt http gd2 mlb com c
  • 用于列出文件夹但排除特定文件夹的批处理脚本

    我希望此脚本列出文件夹名称中包含 deleted 的所有文件夹 但如果它们位于名为 done 的文件夹中则不列出 例如 列出文件夹 如果位于 C temp如果它在C temp random folder name但如果它在C temp do
  • 在 HTML 下拉列表中有一个滚动条

    我正在寻找一种在 HTML 的下拉列表中添加滚动条的方法 这样如果下拉列表包含的内容超过例如 5 项 将出现滚动条以查看其余项 这是因为我将被迫列出一些大清单 过去几个小时我一直在谷歌上搜索它 但没有运气 它需要适用于 IE8 FF 和 C
  • WPF/C# 将自定义对象列表数据绑定到列表框?

    我在将自定义对象列表的数据绑定到ListBox in WPF 这是自定义对象 public class FileItem public string Name get set public string Path get set 这是列表
  • 泛型和系统集合

    迁移到 NET 2 0 后 是否还有理由继续使用 systems Collections 命名空间 除了维护遗留代码之外 是否应该始终使用泛型命名空间 在大多数情况下 泛型集合的执行速度比非泛型集合更快 并且为您带来强类型集合的好处 比较
  • 您能给我解释一下 OCaml 函子吗? [复制]

    这个问题在这里已经有答案了 可能的重复 在函数式编程中 什么是函子 https stackoverflow com questions 2030863 in functional programming what is a functor
  • 任何reinterpret_cast改变指针值的真实例子?

    根据 C 标准 reinterpret cast一个指针的T 到其他类型的指针Q 可以改变或不改变指针值 https stackoverflow com questions 1863069 casting via void instead
  • 清理 STL 指针列表/向量

    您可以想出的最短的 C 块是多少来安全地清理std vector or std list指针 假设您必须对指针调用删除 list
  • 如何使用 Unity 动态注册通用类?

    我有一个包含很多类 300 和 BaseClass 的程序集 我想用接口注册一个泛型类 统一后 您必须在 Name如果你想解析接口的对象数组 我想要一个对象数组主视图模型自动地 有没有办法通过反射来自动执行此操作 有什么建议么 示例 伪 p
  • 找到不固定长度的数字的所有可能排列以达到给定的总和或乘积

    使用普通 Python 或任何 Python 库 您将如何查找列表中元素的所有可能组合l等于给定值val using addition 减法 or 乘法 假设列表的长度并不总是相同 假设列表中的每个元素在每个组合中只能使用一次 并假设没有使
  • Java 泛型从类创建数组

    我有一个层次结构 其中正方形 三角形和圆形都从形状延伸 我有一个工作方法 public void someMethod File file new File File with squares ThirdPartyClass foo new
  • R:将 readRDS 应用于 .Rds 文件名的列表对象

    我有几个包含数据帧对象的 Rds 文件 我想对每个文件应用一个函数并将数据帧绑定到单个数据帧中 但是 当我尝试从文件名列表中读取多个 Rds 文件时 我收到错误 FUN X i 中的错误 从连接读取时出错 readRDS 不适用于列表吗 R
  • 使用 FIND 命令进行并集、交集和排除?

    我需要使用 find 命令管理列表 假设列表在非不同列表中具有随机名称 即它们的交集不是空集 我能怎么做 A B 查找列表A中除列表B中的文件之外的文件 A 路口 B 查找列表 A 和 B 共有的文件 请咨询here https stack
  • 简单的 PHP 条件帮助: if($Var1 = in list($List) and $Cond2) - 这可能吗?

    这是一个可能的功能吗 我需要检查一个变量是否存在于我需要检查的变量列表中 并且 cond2 是否为 true 例如 if row name 1 2 3 Cond2 doThis 它对我不起作用 我在复制粘贴中更改的只是我的列表和变量名称 i
  • F# 如何标记用户输入:分隔数字、单位、单词?

    我对 F 相当陌生 但最近几周一直在阅读参考资料 我希望处理用户提供的输入字符串 识别并分隔组成元素 例如 对于此输入 XYZ 酒店 6 晚 220 欧元 晚 加17 5 的税 输出应该类似于元组列表 XYZ 字 酒店 字 6 数字 夜晚
  • 任意通用列表的通配符

    我有一个类 MyClass 它不是通用的 包含任意 TList 并对其执行某些操作 我希望用通用 TList 替换 TList 但 MyClass 必须保持非通用 由于 Delphi 是不变的 这样的事情是行不通的 list1 TList

随机推荐

  • 从 App Engine 连接到 Kubernetes 引擎

    我们希望使用应用程序引擎灵活的流程来更新位于 Google Kubernetes Engine 上的 ElasticSearch 索引 我们需要通过 http s 地址连接到 ElasticSearch 推荐的方法是什么 我们不想将集群暴露
  • 为什么打字稿编译器在生成的 JavaScript 中省略了“should.js”导入?

    我面临一个奇怪的问题 在我的 可以说 a ts我有
  • C 标准中 char 数组结构成员的对齐

    假设我想读 写 tar 文件头 考虑标准 C C89 C99 或 C11 关于填充 字符数组在结构中是否有任何特殊处理 编译器可以向这样的结构添加填充吗 struct header char name 100 char mode 8 cha
  • numpy 1.8.0 与 py2exe 打包时出现 OMP 警告

    import numpy 当我将上面一行脚本打包为使用 py2exe 的单个可执行窗口应用程序 http www py2exe org index cgi SingleFileExecutable 我在启动时收到以下警告 OMP Warni
  • 无法从PreparedStatement获取OracleSpatial Connection对象

    我正在使用 Hibernate Spatial 4 3 2 和 Hibernate 4 3 11 我的数据库是 Oracle 12c 我使用 hikariCP 作为连接池 当我使用 hikacriCP 时 我收到一个错误 似乎原因是 hib
  • JFrog Artifactory 将什么令牌端点用于其 Docker 注册表?

    我正在尝试编写基本上可以执行以下操作的代码docker inspect发布到私人 JFrog Artifactory 的图像 而无需自己实际提取图像 我一直在使用一个名为在不拉取的情况下检查 Docker 镜像 https ops tips
  • 将 numpy 数组中低于阈值 # 的数字替换为零

    所以我有一个非常大的 Numpy 数组 2560x1920 它实际上来自灰度图片 其中每个像素都被赋予一个 0 1 之间的数字 表示其亮度 我试图用零替换低于阈值 例如 0 5 的所有值 这可能是一个简单的任务 但我是 Numpy 的初学者
  • opencv 视频上的颜色阈值

    I am thresholding for a color range in an opencv video The goal is to seperate the B mode black and white information on
  • 列表项未正确删除(React)

    如果我的笔记应用程序能提供一些帮助 我将不胜感激 假设我的笔记列表中有 3 个笔记 我想删除列表顶部的注释 无论我尝试删除哪一个 总是首先删除列表最底部的注释 我检查了 React 控制台 应用程序组件状态中的注释数组表明它已正确删除 但从
  • 在 Linux 中使用仅限 CLI 的工具生成磁盘使用情况图/图表

    在这个问题中 https stackoverflow com questions 32230 tracking down where disk space has gone on linux有人询问如何在 Linux 中显示磁盘使用情况 我
  • 改变路径或细化

    我想改变a b在一个块内a c 或者甚至可能a 我这样做的正常方法是change test a b change test 1 c 但它只改变了第一部分 即a to c gt gt test c b 无法访问路径test 2 either
  • HTTP/2 世界中的 WebSocket 替代方案是什么?

    新的 HTTP 2 协议具有一些有前途的功能 他们中有一些 多路复用 单个 TCP 连接可用于发出多个 HTTP 2 请求并接收多个响应 到单个源 HTTP 2 服务器推送 将服务器响应发送到客户端而不接收请求 即由服务器发起 双向连接 H
  • Pytorch GPU 使用率低

    我正在尝试 pytorch 的例子https pytorch org tutorials beginner blitz cifar10 tutorial html https pytorch org tutorials beginner b
  • 错误:集合方法聚合是同步的

    我正在尝试以下代码 const Conn mongoose createConnection mongodb 127 0 0 1 27017 db const addresses Conn collection users aggregat
  • ASP.NET 代码表达式、数据绑定和其他声明式表达式

    这些标签有什么区别 更重要的是 如何在 ASP NET 控件中使用声明性语法显示页面属性 我正在尝试在 ASP NET 控件中执行此操作 任务是设置标签的文本 但如果我想更改输出控制 我不想以语法方式执行此操作 我收到有关服务器端控件不能包
  • ICollection / ICollection 歧义问题

    只是想进行简单的扩展句法糖 http en wikipedia org wiki Syntactic sugar public static bool IsNotEmpty this ICollection obj return obj n
  • 如何在 Android Studio 中使用 git 分支

    我是 git 新手 我有一个非常简单的使用 git 的场景 我的第一个版本是用 Android Studio 编写的 现在我想使用一些新功能 到目前为止我做了什么 在我的 Android Studio 中启用 VCS 从 Android S
  • Pathogen 不加载插件

    病原体对我不起作用 我正在遵循 Adam Lowe 发布的提示here http www adamlowe me 2009 12 vim destroys all other rails editors html 还有更多 没有任何成功 我
  • NoneType 对象不可下标

    我正在 Learnstreet 上进行一个七段显示项目 所需方法之一获取从标记为 inputString 的文本框获得的输入 然后使用将输入字符串传递给给定方法text这是一个字符串 该方法的进一步描述如下 在这个方法中 我们从输入字符串中
  • 如何在 F# 中将对象转换为泛型类型列表

    在下面的代码片段中 我的目的是将 System Object 可能是 FSharpList 转换为它所持有的任何泛型类型的列表 match o with list lt gt gt addChildList o gt list lt gt