views:

104

answers:

3

I'm wondering how you'd recommend designing a class, given the fact that XNA Framework uses Struct all over the place?

For example, a spite class, which may require a Vector2 and a Rectangle (both defined as Struct) to be accessed outside of the class.

The issue come in when you try to write code like this:

class Item 
{
    public Vector2 Position {get; set;}
    public Item() { Position = new Vector2(5,5); }
}

Item i = new Item();
i.Positon.X = 20; // fails with error 'Cannot modify the return value of Item because it is not a variable.'

// you must write code like this
var pos = i.Position;
pos.X++;
i.Position = pos;

The second option compiles and works, but it is just butt ugly. Is there a better way?

+4  A: 

Add a method to your item class something like:

public void Move(int xAmount, int yAmount)
{
   var newPosition = new Point(this.Position.X + xAmount, this.Position.Y + yAmount);
   this.Position = newPosition;
}

That way the uglyness is nice and abstracted so you can just call the method like this:

i.Move(1,1)

which would move it down to the right one pixel. You could have variations of this method like MoveRight() MoveLeft() etc..

BFree
+2  A: 

You can abstract away the struct as well:

private Vector2 position;
public float X
{
    get
    {
        return position.X;
    }
    set
    {
        position.X = value;
    }
}

And use it like this:

Item i = new Item();
i.X = 20;
Bob
-1: it works, but mutating structs is evil. http://blogs.msdn.com/ericlippert/archive/2008/05/14/mutating-readonly-structs.aspx
Juliet
@Juliet This isn't a self-mutating struct as is mentioned in that blog link. What I'm doing is fundamentally no different than using any other private value type variable within a property. A float is returned by the get, and the private struct is updated as it should be in the set. It works because it's not evil and no copies are being dealt with
Bob
+4  A: 

Or, just to throw this out there ... just expose the field. There's nothing inherently wrong with exposing a public field.

For example, if your entity exposes a Vector3 for it's position so that other things can use that value in their own calculations ... just expose it. Otherwise, if no other class or entity needs to know the position, do not expose it at all :-)

Here is some sage advice from Rico Mariani:

Generally, my feeling is that properties are highly overrated and fields terribly under-utilized. Did I mention that not everyone agrees with this position? :)

Joel Martinez
So you are saying do something like this `public Vector2 Position;` as a replacement for `public Vector2 Positin {get; set;}`
Nate Bross
Yep, actually ... updated the answer with a link to a great post by Rico Mariani
Joel Martinez
There's nothing wrong with it only if your class doesn't expect to update other things when the position changes, or doesn't need to do some special calculation for movement, or anything like that.
Bob