Reputation: 33
I have a base class with a static variable. I want to create derived subclasses which will automatically have their own unshared static variable. Ideally it would look like this:
class Parent
{
Texture2D picture;
static Texture2D pictureOrigin;
Parent()
{
picture = pictureOrigin;
/*Loading the static origin to an instance variable
because I might want to have more pictureOrigins
and alternate them or perhaps change the picture
of the instance based on a certain event, etc.*/
}
}
class Subclass1 : Parent
{
Subclass1() : base()
{ }
}
class Subclass2 : Parent
{
Subclass2() : base()
{ }
}
void main()
{
Parent.pictureOrigin = Load("pictureForParent");
Subclass1.pictureOrigin = Load("pictureForSubclass1");
Subclass2.pictureOrigin = Load("pictureForSubclass2");
//Then creating instances of the classes and drawing them, etc.
}
But what happens is that they all get the last loaded image (pictureForSubclass2) because the static variable pictureOrigin
is shared between them.
The quickest fix is manually adding new static variable pictureOrigin
to each subclass and hiding the pictureOrigin
variable of the base class:
class Subclass1 : Parent
{
new static Texture2D pictureOrigin;
Subclass1() : base()
{
picture = pictureOrigin;
}
}
Alternatively, creating abstract methods or similar to ensure the creation of the new static variable in the subclasses. But it seems like too much of a hassle and not too elegant. Is there a better way of doing this?
Upvotes: 0
Views: 2322
Reputation: 9766
A static member that declared in generic type is basically declared per class and its generic.
For example Foo<Bar>.baz
is not equal to Foo<Qux>.baz
.
So basically you can do this:
abstract class Parent<T>
{
Texture2D picture;
static Texture2D pictureOrigin;
Parent()
{
picture = pictureOrigin;
/*Loading the static origin to an instance variable
because I might want to have more pictureOrigins
and alternate them or perhaps change the picture
of the instance based on a certain event, etc.*/
}
}
class Parent : Parent<Parent>
{
Parent () : base()
{ }
}
class Subclass1 : Parent<Subclass1>
{
Subclass1() : base()
{ }
}
class Subclass2 : Parent<Subclass2>
{
Subclass2() : base()
{ }
}
void main()
{
Parent.pictureOrigin = Load("pictureForParent");
Parent<Subclass1>.pictureOrigin = Load("pictureForSubclass1");
Parent<Subclass2>.pictureOrigin = Load("pictureForSubclass2");
}
Upvotes: 0
Reputation: 17171
Your question smells like a poor design. Static variables are generally poor practice in my opinion, and proper object-oriented design can eliminate the need to ever use static members.
Try refactoring like so:
public class Parent
{
private Texture2D texture;
public Parent(Texture2D texture) {
this.texture = texture;
}
public Texture2D Picture { get {
return texture;
}
}
}
public class SubClass1 : Parent
{
public SubClass1(Texture2D texture) : base(texture) {
}
}
Let me elaborate on why static is a poor choice:
Upvotes: 1
Reputation: 29244
You can do this with a static Dictionary<Type,Texture2D>
.
public class Parent
{
// Keep a table of types and default values
protected static Dictionary<Type, Texture2D> pictureOrigin;
static Parent()
{
// static ctor. initialize table
pictureOrigin=new Dictionary<Type, Texture2D>();
}
internal static void SetDefaultPicture<T>(Texture2D picture)
{
// Set default based on type T
Type type=typeof(T);
pictureOrigin[type]=picture;
}
public Parent()
{
// Assign default based on this type
Picture=pictureOrigin[this.GetType()];
}
public Texture2D Picture { get; set; }
}
public class SubClass1 : Parent
{
}
public class SubClass2 : Parent
{
}
to be used as
static void Main(string[] args)
{
Texture2D picture0 = Load("pictureForParent");
Texture2D picture1=Load("pictureFroSubClass1");
Texture2D picture2=Load("pictureFroSubClass2");
Parent.SetDefaultPicture<Parent>(picture0);
Parent.SetDefaultPicture<SubClass1>(picture1);
Parent.SetDefaultPicture<SubClass2>(picture2);
}
Here is the debug of an example. It shows that SubClass1
initialized with pictureForSubClass1
automatically.
Upvotes: 1