-1

I have a ConcurrentDictionary:

Node n = new Node()
{
    Id = 1,
    Title = "New title"
};
this.nodes.AddOrUpdate((int)n.Id, n, (key, existingVal) =>
    {
        existingVal.Update(n);
        return existingVal;
    });

My Node class implements Update which update all properties on the object to be updated. This works fine but it seems ridiculous that I have to write it every time since it's the same for all cases.

I can create a Func and a function to use since it's always the same:

...
new Func<int, Node, Node>(UpdateNode)
...

private Node UpdateNode(int id, Node node)
{
    return node;
}

How can I implement a function where I can also access n?

Asken
  • 7,679
  • 10
  • 45
  • 77
  • *How can I implement a function where I can also access n?* Please clarify your question. What do you mean? That's exactly what your code does. – Yuval Itzchakov Oct 21 '15 at 07:56
  • @Yuval Itzchakov Seems like Luaan got the question... – Asken Oct 21 '15 at 08:00
  • Update method in the node is Private ? It needs int, node as input, but you are calling it as **existingVal.Update(n)**, not even an extension method. Am I missing something. If everything is in place then why would **existingVal.Update(key,n)** not work as resulf of Func, something like: **(key, existingVal) =>existingVal.Update(key,n)** in your original code itself – Mrinal Kamboj Oct 21 '15 at 08:39
  • @Mrinal-Kamboj The `existingVal.Update(n);` is not the same method as the `Update`-function. I can see the confusion there... edited the question. – Asken Oct 21 '15 at 09:12

1 Answers1

4

In your original code, n is captured in a closure. Since you don't have the n to close over when declaring your Func, you need to use a different Func:

Func<int, Node, Node, Node> myFunc;

Now, this doesn't fit the definition of the AddOrUpdate argument. This is okay - you need to pass the closure anyway:

this.nodes.AddOrUpdate((int)n.Id, n, (key, val) => myFunc(key, val, n));

However, since we're already on the road, why not make this even better? There's nothing preventing you from writing your own method that handles all of this:

public static void AddOrUpdate(this ConcurrentDictionary<int, Node> @this, Node newNode)
{
  @this.AddOrUpdate((int)newNode.Id, newNode, (key, val) => 
    {
      val.Update(newNode);
      return val;
    });
}

Which can be used simply as so:

this.nodes.AddOrUpdate(n);
Luaan
  • 62,244
  • 7
  • 97
  • 116
  • That's perfect! I tried making an extension but didn't get all the way. Now I think I got that too. Long time away from c#... – Asken Oct 21 '15 at 08:08