You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

F#类中Dictionary操作异常求助:添加元素后仍报KeyNotFoundException

F#类中Dictionary赋值异常分析

我近期开始学习F#,并在个人项目中尝试用多种语言实现康威生命游戏,目前遇到类内Dictionary赋值的问题。

问题代码

module World

open System.Collections.Generic

type World() =
  member private this.cells = new Dictionary<string, int>()
  
  member this.add_cell(): int =
    printfn "%A" this.cells
    this.cells.Add("0-0", 123)
    printfn "%A" this.cells
    this.cells["0-0"]

let world = new World()
world.add_cell() |> ignore

运行输出

seq []
seq []
Unhandled exception. System.Collections.Generic.KeyNotFoundException: The given key '0-0' was not present in the dictionary.
   at System.Collections.Generic.Dictionary`2.get_Item(TKey key)
   at World.World.add_cell()

异常现象

  • 本应为Dictionary的this.cells打印显示为seq []
  • 添加元素后打印this.cells仍为空
  • 获取刚添加的键值时触发KeyNotFoundException

原因分析与解决方法

核心问题是你把cells定义成了计算型成员,而非类的私有字段。在F#中,member private this.cells = new Dictionary<string, int>()这种写法会让每次访问this.cells时,都重新创建一个全新的Dictionary实例:

  1. 两次打印this.cells时,都是生成新的空字典,所以显示为seq [](Dictionary实现了IEnumerable,%A格式化会按序列输出)
  2. 调用this.cells.Add是给临时生成的字典加元素,操作完成后这个临时字典就被丢弃了
  3. 最后访问this.cells["0-0"]时,又创建了新的空字典,自然找不到对应的键

要解决这个问题,需要把cells定义为类实例的私有字段,确保整个实例生命周期内只初始化一次:

方法一:使用构造函数绑定字段(推荐)

module World

open System.Collections.Generic

type World() =
  // 定义私有字段,仅在实例创建时初始化一次
  let cells = new Dictionary<string, int>()
  
  member this.add_cell(): int =
    printfn "%A" cells
    cells.Add("0-0", 123)
    printfn "%A" cells
    cells["0-0"]

let world = new World()
world.add_cell() |> ignore

方法二:使用val关键字定义字段

module World

open System.Collections.Generic

type World() =
  // 声明私有字段
  [<DefaultValue>]
  val private cells : Dictionary<string, int>
  // 在构造函数代码块中初始化字段
  do
    this.cells <- new Dictionary<string, int>()
  
  member this.add_cell(): int =
    printfn "%A" this.cells
    this.cells.Add("0-0", 123)
    printfn "%A" this.cells
    this.cells["0-0"]

let world = new World()
world.add_cell() |> ignore

两种写法都能保证所有操作针对同一个Dictionary实例,运行后就能正常输出添加的键值对,不会再抛出异常。


内容的提问来源于stack exchange,提问作者Kieran Pilkington

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 19:07:14