自己的溯源函数注意点

核心结论

你说得完全正确:就你当前「图层前缀统一过滤」这个场景,完全没必要拆成两个独立委托参数、写两份一模一样的过滤代码。分开做两套参数属于过度设计。

下面把底层逻辑拆开讲清楚:

1、什么时候适合分开两个委托(pipeFilter / pointFilter)

只有一种场景值得分开:管线、管点的过滤规则不一样 。

举几个现实例子:

  1. 拓扑回溯时:管线要求前缀=ws,但是管点不受图层限制,任何图层的节点都可以作为中转;
  2. 管线要校验XData管网类型,管点只校验图层;
  3. 禁止穿过雨水管线,但是雨水节点可以被选中,不阻断路径。

管线过滤有一个非常特殊的身份:它同时承担「结果筛选」+「链路阻断器」两个职责

而原先代码里的管点过滤,仅仅只是:这个点要不要放进结果集合,不能阻断遍历前进 。

这也是当初我分开两个参数的根本原因 ------ 二者在回溯流程里作用位置、产生的影响完全不同,即使过滤条件碰巧一样,语义角色不一样。

2、什么时候完全可以只用1个统一过滤函数

当你的业务规则满足:

管线、管点,使用完全一模一样的判断条件。

这时你只需要传一个委托 ,管线校验用它、管点校验也复用它一份即可。

不需要新增第二个形参。

3、还有一个很关键的语义区别(最容易踩坑)

复制代码
管线过滤 → 不满足 → continue;链路切断,上游不再往前走(影响遍历路径)
管点过滤 → 不满足 → continue;只是这个点不加入结果,但是遍历路径不受任何影响

哪怕判断函数代码一模一样,二者产生的后果不是一回事。

举个例子:

链路 ysA‑ys管‑ws节点‑ys管‑ysB

  • 如果管线不过滤、只给管点加图层前缀过滤:
    ws节点不会被加到结果,但是队列仍然会穿过ws节点,跑到另一边 ys‑B。
  • 如果管线过滤:遇到ws管线直接停止,整条路断掉。

所以:函数代码相同 ≠ 在回溯里产生的效果相同。

4、给你最优的取舍思路

方案A(适合你现在:图层前缀过滤)

只增加单个可选委托参数 Func<ObjectId,bool> entityFilter

管线判断时调用它;收集管点的时候,也调用同一个委托。

一份逻辑,两处复用。简洁够用,没有冗余。

方案B(预留扩展,面向未来复杂规则)

保留两个独立参数 pipeFilter / pointFilter。

  • 当前调用:传同一个委托实例进去,两份代码不用重复写;
  • 以后哪天管线、管点过滤逻辑分叉了,你不用再去改 TraceUpstream 的函数签名、到处修改调用代码。

代价就是接口多了一个参数,属于为未来功能预留的扩展设计。

5、对你当前项目的建议

现阶段图层前缀过滤,选方案A,单委托就足够,不需要双参数 。

等到后面你出现:管线限制条件 和 管点限制条件不一样的时候,再拆分成两个独立过滤委托即可。

如果你需要,我后面可以给你改成单‑委托版本的回溯代码。

相关推荐
波力海苔夹心脆67519 小时前
C# WPF 资源字典详解:ResourceDictionary、MergedDictionaries 与自定义控件案例
开发语言·c#·wpf·入门教程·resource·资源字典
AI导出鸭PC端1 天前
Perplexity批量导出没有PDF模式?AI导出鸭插件补上最后一块拼图
人工智能·pdf·c#·ai导出鸭
Risehuxyc1 天前
C# 选用更流行的语言版本
c#
淡海水2 天前
09-04-内存-Unity原生对象生命周期
unity·c#·游戏引擎·gc
吴可可1232 天前
富怡CAD二次开发指南
c#
1-1=02 天前
C# IO和序列化
c#·.net·.netcore
寂寞的船2 天前
【Unity Bug挑战】第10期 SerializeReference 内存泄漏之谜
unity·c#·游戏引擎·bug
CSharp精选营2 天前
从控制台到「会动手」的 AI:用 Semantic Kernel 搭应用(小白教程)
c#·.net·ai agent·semantickernel·functioncalling
宝桥南山3 天前
.NET 11 - 尝试一下Blazor中的新特性SupplyParameterFromTempData
microsoft·微软·c#·asp.net·.net·.netcore
1-1=03 天前
C# 中 Lambda、Linq 与 Expression
c#·linq