I've got a "Vector" struct which stores a x, y, and z values. In an effort to make them easier to access I added an index operator, like this:
public struct Vector
{
public double x;
public double y;
public double z;
public double this[int i]
{
get
{
if(i == 0) return x;
else if(i == 1) return y;
else if(i == 2) return z;
else throw new ArgumentOutOfRangeException("i", i, "Index must be 0, 1, or 2");
}
set
{
if (i == 0) x = value;
else if (i == 1) y = value;
else if (i == 2) z = value;
else throw new ArgumentOutOfRangeException("i", i, "Index must be 0, 1, or 2");
}
}
}
Note: Normally I would use an array instead of x, y, z but I'm working with pre-existing code and it'll be difficult to refactor at this point.
Now if I use a struct as an auto-property in a class and then try to modify its xyz values, I get this
public Vector v{ get; set; }
void funct(){
for(int i = 0; i < 3; i++)
{
v[i] = 3.0;
}
}
I get a compiler error:
"Cannot modify the return value of "v" because it is not a variable"
I've tried googling for the error, but I don't think anyone has done this the way I did (it's a pretty interesting case I guess, and probably really ugly). What would be the right way to solve this problem? Is it wrong to use the index operator like this?
Note: yes, I know this is a mutable struct. Again, pre-existing code
You got some options:
class
instead of a struct
Obtain a copy of the struct value first, modify it, then put it back:
Vector temp = v;
for(int i = 0; i < 3; i++)
{
temp[i] = 3.0;
}
v = temp;
Make it immutable and add helper/factory methods:
public struct Vector
{
....
public Vector WithX(double x)
{
return new Vector(x, this.y, this.z);
}
I would personally go for nbr. 3 as mutable structs (as you've seen) is a pain in the a**.