15

Hello I'm having trouble figuring this out. I have these structs and classes.

struct Circle
{ ... }

class Painting
{
     List<Circle> circles;

     public List<Circle> circles
     {
          get { return circles; }
     }
}

I am trying to modify one of the circles inside the painting class from outside it, using this code:

MutatePosition(ref painting.Circles[mutationIndex], painting.Width, painting.Height);

This line is giving me a compiler error:

A property, indexer or dynamic member access may not be passed as an out or ref parameter

Why is this, and what can I do to solve it without changing my code too much?

CantMutate
  • 153
  • 1
  • 1
  • 4

2 Answers2

33

The error is pretty clear - you can't pass a property to a ref parameter of a method.

You need to make a temporary:

var circle = painting.Circles[mutationIndex];
MutatePosition(ref circle, painting.Width, painting.Height);
painting.Circles[mutationIndex] = circle;

That being said, mutable structs are often a bad idea. You might want to consider making this a class instead of a struct.

Reed Copsey
  • 554,122
  • 78
  • 1,158
  • 1,373
  • Just a question, why does accessing the struct like I was doing count as accessing a property? I could understand if I was accessing the list itself. – CantMutate Jan 27 '11 at 06:27
  • @CantMutate: You *are* accessing the property: `ref painting.Circles[mutationIndex]`. That's using an indexer (which is a kind of property) after fetching the list via a property. – Jon Skeet Jan 27 '11 at 06:28
  • 1
    @Jon Skeet: Thanks, perhaps it's time to go back to the C# book! – CantMutate Jan 27 '11 at 06:29
  • +1, But this doesn't have much to do with mutable structs. Look at the corrected sample you've posted; there's no requirement that `Circle` be a mutable type for it to work. `MutatePosition` could replace the storage location for `circle` entirely with a new `Circle`, and the changes would filter through. – Ani Jan 27 '11 at 06:33
  • @Ani: Of course - I was suggesting that mutable structs are a bad idea - separate from this problem. It was a more of "this might be better off as a class" comment. – Reed Copsey Jan 27 '11 at 16:30
  • Ok. I still don't understand the "this might be better off as a class" idea, unless of course there's some suggestion which I've missed that the struct in question is mutable . – Ani Jan 27 '11 at 16:37
  • @Ani: The struct's obviously mutable - otherwise, there'd be no reason to pass it by ref ;) The "mutationIndex" is a good hint, too... – Reed Copsey Jan 27 '11 at 16:38
  • This answer is not useful.Even if you didn't tell this, We would have tried it only. – Tamilmaran Feb 13 '12 at 12:50
2

If there's only one ref param and no return type for MutatePosition you can return the value.

painting.Circles[mutationIndex] = MutatePosition(circle, painting.Width, painting.Height);

If there are multiple ref params and/or already a return type you can create a new type that includes everything that needs to be returned.

class MutateResults() { Circle Circle; object OtherReffedStuff; }
ShawnFeatherly
  • 2,470
  • 27
  • 20