1

I have a Rectangle property in my class, which I'd like to make accept Width and Height correctly, and also return them, as if I was dealing with a normal Rectangle.

Vector2 position;
Rectangle rectangle;
public Rectangle Rect
    {
        get { return rectangle;  }
        set { rectangle = value; position.X = value.X; position.Y = value.Y; }
    }

Seems fine, works great. Except for when you want to get or set Width or X specifically.

How do I make that possible?

4

1 回答 1

2

If the semantics of your class are such that you can be 100% certain that you're never going to care when outsiders adjust Rect, just expose it as a field and callers will be able to set its fields directly. If you cannot make that guarantee, then you might consider offering a method which passes rectangle to a callback method:

delegate void ActionByRef<T1>(ref T1 p1, ref T2 p2);
delegate void ActionByRef<T1,T2>(ref T1 p1, ref T2 p2);
delegate void ActionByRef<T1,T2,T3>(ref T1 p1, ref T2 p2, ref T3 p3);
void ActOnRect(ActionByRef<Rectangle> proc)
  { proc(ref rectangle); position.X = value.X; position.Y = value.Y; }
void ActOnRect<TP1>(ActionByRef<Rectangle,TP1> proc, ref TP1 p1)
  { proc(ref rectangle, ref p1); position.X = value.X; position.Y = value.Y; }
void ActOnRect<TP1,TP2>(ActionByRef<Rectangle,TP1> proc, ref TP1 p1, ref TP2 p2)
  { proc(ref rectangle, ref p1, ref p2); position.X = value.X; position.Y = value.Y; }

That approach will avoid anyone having to make a copy of rectangle just to change one of its members. Probably not worth it with a 16-byte structure, but maybe worthwhile if a larger structure is necessary.

A third approach would be to simply require your callers to do something like:

var r = myThing.Rect;
r.X = 23;
myThing.Rect = r; // Or perhaps myThing.SetRect(R);

The final approach I'd suggest would be to follow the pattern of Control.SetBounds, which includes an overload that takes the Rectangle members as separate parameters, but takes an additional parameter which specifies which parameter or parameters should be copied to the appropriate members of Bounds.

于 2013-01-13T04:41:27.343 回答