我有一个我在运行时定义的委托。我希望它检查字典是否包含特定键。其中一个委托参数是字典的ref
,因此字典始终是最新版本(不是冻结副本)。
然而,查找的关键是object
字段,但我不想将ref
传递给该对象。我只想抓取字段值并使用它,就好像它是一个常量(冻结副本)。
这是确切的代码段。我将一个引用传递给netController,它允许我使用ContainsID()
检查一些内容。 ID参数来自msg
对象,但我只想使用该值而不引用容器对象。
Func<netController, bool> resolveFunc = delegate (netController nc)
{
return nc.ObjectRegister.ContainsID(msg.parentObjectID);
};
nc
在此委托的范围内,但msg
不在此范围内。这是可行的,还是所有东西都需要作为参数传递?
注意:我说字典,但它实际上是一个字典对象。 ContainsID()
是ContainsKey()
的包装器。别担心这部分。
答案 0 :(得分:1)
这被称为委托对变量的隐式捕获,这绝对是可能的。
只要msg
在创建代理的行之外的范围内,C#就会捕获它,并允许您在代码中使用它:
Func<Controller,bool> MakeChecker(Message msg) {
return nc => nc.ObjectRegister.ContainsID(msg.parentObjectID);
}
上面的方法从创建委托的上下文中隐式捕获msg
,而不是将其作为委托参数传递。我使用lambda语法代替匿名委托语法:
Func<Controller,bool> MakeChecker(Message msg) {
return delegate (netController nc) {
return nc.ObjectRegister.ContainsID(msg.parentObjectID);
}
}
如何将其存储到代理中?
像这样:
Message msg = ...
Func<Controller,bool> myChecker = MakeChecker(msg);