Captured variables

  • Thread starter Thread starter Peter Morris
  • Start date Start date
P

Peter Morris

var result = new List<StockLevelRow>();
foreach(SomeClass c in SomeList)
result.Add(
new StockLevelRow(c.Name,
delegate() { return c.StockLevel; },
delegate(int value) { c.StockLevel = value; }
)
);

This is a PITA because the last variable assigned to "c" is captured by each
of the two delegates. Is there a simple workaround for this? If not then I
am going to have to make my StockLevelRow class abstract and create a
concrete descendant for each different way I have of obtaining/setting the
StockLevelRow.Quantity (which currently uses a get and set delegate passed
to it).


Thanks


Pete
 
var result = new List<StockLevelRow>();
foreach(SomeClass c in SomeList)
    result.Add(
        new StockLevelRow(c.Name,
            delegate() { return c.StockLevel; },
            delegate(int value) { c.StockLevel = value; }
        )
    );

This is a PITA because the last variable assigned to "c" is captured by each
of the two delegates.  Is there a simple workaround for this?  If notthen I
am going to have to make my StockLevelRow class abstract and create a
concrete descendant for each different way I have of obtaining/setting the
StockLevelRow.Quantity (which currently uses a get and set delegate passed
to it).

Copy the variable:

var result = new List<StockLevelRow>();
foreach(SomeClass c in SomeList) {
SomeClass copy = c;
result.Add(
new StockLevelRow(copy.Name,
delegate() { return copy.StockLevel; },
delegate(int value) { copy.StockLevel = value; }
)
);
}

Jon
 
I decided to keep the original + more complicated code that already existed
(descendant classes) for now. I will remember your tip for next time I need
it, thanks! :-)
 
It's a PITA if it is causing me a PITA. Whether or not it is supposed to
cause me a PITA is irrelevant :-)
I do wonder if what you're doing wouldn't be better addressed using an
interface that defines the property you seem to be implementing via
anonymous methods here, but that's a different question altogether. :)
<<

I agree that it is more like an interface and to be "more proper" should be
implemented as an interface. However, this would result in the same thing,
lots of subclasses :-) I am basically binding a reusable GUI "Record Stock
Levels" to different classes, so this is acting like a mediator.

Case 1:
Quantity maps to StockCheck.QuantityOnHand

Case 2:
Quantity maps to Replenishment.QuantityAdded

Case 3:
Quantity maps to Replenishment.OpeningLevel

and so on, there are about 6 cases. I just thought having a single class
with delegates for Get/Set quantity would be easier than having to write a
mediator for each class. I don't want to add an interface to StockCheck etc
because the interface would be for GUI purposes only, and I don't like
adding GUI specific stuff to my business classes, it's a PITA ;-)

Knowing that a local variable will do the trick is useful information that I
will put to good use in future.


Pete
 
The variable capturing rules are the way the are for consistency, and if  
it _didn't_ work that way, it could be a genuine "PITA" for other  
scenarios.

To be honest, I can hardly come up with a scenario where the existing
rule for capturing of the foreach variable (or rather, the rule for
the scoping of that variable seen in context of capturing) would be
useful. I wonder why they didn't just move the declaration of the
variable in foreach expansion inside the loop body when they
introduced closures in 2.0.
 
Pavel Minaev said:
To be honest, I can hardly come up with a scenario where the existing
rule for capturing of the foreach variable (or rather, the rule for
the scoping of that variable seen in context of capturing) would be
useful. I wonder why they didn't just move the declaration of the
variable in foreach expansion inside the loop body when they
introduced closures in 2.0.

Indeed - especially as the natural way of reading "for each int i" is
that there are multiple "i" variables. On the other hand, that would be
inconsistent with "for" (which really does only declare variables
once).
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Back
Top