There I am making a 2D game in C# XNA 4.0, and run across yet again a petty annoyance of mine; the Rectangle. For those using basic collision, this is almost a necessity. For almost any game object created you need to have a rectangle. Then I go to change the X, check collision, or anything else. And there I begin the never-ending battle of objectName.Rectangle.Whatever
. To get around this I of course give the class of objectName properties/methods that access these for me.
Then I dared to dream. I had grand designs to make a basic game object class that everything drawable would inherit from, that would allow parenting, precise local coordinates (floats), and hold the texture/spritebatch. To make this complete I was ready to inherit from Rectangle, to use all the methods and attributes that it holds. Heck, whenever something required a Rectangle, I could be so lazy as to say objectName, not objectName.Rectangle.
Then I realized, not a chance. I started out depressed as my oh-so-clever idea was smashed to bits. Since then my perfect little class holds a rectangle, with various methods and properties accessing it as needed. I have also taken the chance to have it inherit from the XNA DrawableGameComponent. While in the long run this has been more practical, every time I view a draw or update method and see the call to rectangle I often wonder, was there ever a hope to do what I had wanted? Was there some clever work around that I could have done? Or was inheriting from a Rectangle truly sealed from my grasp?
While using the DrawableGameComponent class provided in XNA allows most game-object related actions happen inside the classes Update() method, every time outside of a class I need to reference not to property of a Rectangle, but rather the Rectangle itself, I am slightly peeved considering that in really every way my object is, in fact, and souped-up Rectangle. And then once again I can find myself asking:
Is there any way to inherit from a pre-defined struct, or give the project the impression you are (a work-around)?
No you cannot. C does not support the concept of inheritance.
Structs cannot have inheritance, so have only one type. If you point two variables at the same struct, they have their own independent copy of the data. With objects, they both point at the same variable.
Yes, struct can inherit from class in C++. In C++, classes and struct are the same except for their default behaviour with regards to inheritance and access levels of members.
A structure type can't inherit from other class or structure type and it can't be the base of a class. However, a structure type can implement interfaces. You can't declare a finalizer within a structure type.
Inherit no, but you can add a lot of 'default' functionality to the Rectangle object with extension methods. For example
//(inside a static class)
public static int GetSurface(this Rectangle rect){return rect.Width * rect.Height;}
//calling
Rectangle rect;
var s = rect.GetSurface();
That said, what I normally do is encapsulate said struct. Use that class as the base object, and add an operator so that it can be implicitly cast to a Rectangle. That way it can be passed to a method that needs a rectangle without casting.
public class MyRect //class so you can inherit from it, but you could make your own struct as well
{
public int X { get; set; }
public int Y { get; set; }
public int Width { get; set; }
public int Height { get; set; }
public int Right { get { return X + Width; } }
public int Bottom{ get { return Y + Height; } }
public static implicit operator Rectangle(MyRect rect)
{
return new Rectangle(rect.X, rect.Y, rect.Width, rect.Height);
}
public static implicit operator MyRect(Rectangle rect)
{
return new MyRect { X = rect.X, Y = rect.Y, Width = rect.Width, Height = rect.Height };
}
}
}
Now you can create your own rect manually or from an existing one:
MyRect rect = ARectangleVar
And you can use it in legacy methods that expect a Rectangle without casting
Here's a possible workaround (put this in MyClass
, the class you speak of that has a Rectangle property):
public static implicit operator Rectangle(MyClass obj)
{
return obj.Rectangle;
}
This will, e.g. allow you to pass your object to a method expecting a Rectangle
, and it work. Note that unlike with true inheritance, the Rectangle that exists isn't the same instance of MyClass
that you passed in, it's just a struct made from the value.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With