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

为何List.IndexOf查找lambda表达式形式的Action时返回-1?

为什么List.IndexOf查找lambda表达式返回-1?

这个问题的核心在于委托的相等性判断规则,以及lambda表达式的创建机制,咱们一步步拆解:

1. Lambda表达式每次创建都是新的委托实例

当你写() => DisplayTextBlock(...)这样的lambda时,编译器会为每次这样的写法生成一个全新的匿名方法委托实例——哪怕代码逻辑完全一模一样,它们也是内存中不同的对象。List<T>.IndexOf默认用引用相等性(针对引用类型)查找元素,所以两个看起来一样的lambda,本质是不同的对象,自然找不到。

2. 你的代码里的双重问题

再看你的具体代码:

  • 你添加到列表里的是() => DisplayTextBlock(block3 = new TextBlock("3.some text here")),这个lambda包含block3 = new TextBlock(...)的赋值操作;
  • 而你用来查找的是() => DisplayTextBlock(block3),这不仅是全新的委托实例,连执行逻辑都和列表里的那个不一样(一个是先创建赋值再调用,一个是直接调用已存在的变量)。

哪怕你把查找的lambda改成和添加时完全相同的代码,结果还是返回-1,因为它依然是新的委托实例。

解决办法

办法一:存储委托实例到变量再使用

如果你需要后续能找到这个Action,先把它赋值给一个变量,再添加到列表,查找时直接用这个变量:

// 先定义变量存储委托
Action showBlock3 = () => DisplayTextBlock(block3 = new TextBlock("3.some text here"));
// 添加变量到列表
textDisplay.Add(showBlock3);
// 查找时直接用这个变量
myActiveTextIndex = textDisplay.IndexOf(showBlock3);

这样因为是同一个委托实例,IndexOf就能正确找到对应的索引。

办法二:自定义匹配逻辑(如果无法提前存储变量)

如果没办法提前保存委托实例,你可以遍历列表,通过自定义条件匹配。比如给每个TextBlock加个标识属性,然后在遍历的时候检查:

// 假设TextBlock有个Id属性用来标识
int targetId = 3;
myActiveTextIndex = textDisplay.FindIndex(action => {
    // 这里需要根据实际场景,获取当前Action对应的TextBlock标识
    // 比如创建lambda时捕获对应的ID:
    // 创建时:int id = 3; textDisplay.Add(() => DisplayTextBlock(block3 = new TextBlock(id, "3.some text here")));
    // 核心是找到能唯一识别这个Action的特征,进行匹配
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 19:07:35