C#委托使用对象字段的值而不引用

时间:2017-11-01 11:34:23

标签: c# delegates

我有一个我在运行时定义的委托。我希望它检查字典是否包含特定键。其中一个委托参数是字典的ref,因此字典始终是最新版本(不是冻结副本)。

然而,查找的关键是object字段,但我不想将ref传递给该对象。我只想抓取字段值并使用它,就好像它是一个常量(冻结副本)。

这是确切的代码段。我将一个引用传递给netController,它允许我使用ContainsID()检查一些内容。 ID参数来自msg对象,但我只想使用该值而不引用容器对象。

Func<netController, bool> resolveFunc = delegate (netController nc)
{
    return nc.ObjectRegister.ContainsID(msg.parentObjectID);
};

nc在此委托的范围内,但msg不在此范围内。这是可行的,还是所有东西都需要作为参数传递?

注意:我说字典,但它实际上是一个字典对象。 ContainsID()ContainsKey()的包装器。别担心这部分。

1 个答案:

答案 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);