我有一个带有静态变量的基类。我想创建派生的子类,它们将自动拥有自己的非共享静态变量。理想情况下它看起来像这样:
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.
}
但是会发生的是它们都获得了最后加载的图像(pictureForSubclass2),因为静态变量pictureOrigin
在它们之间共享。
最快的解决方法是手动向每个子类添加新的静态变量pictureOrigin
并隐藏基类的pictureOrigin
变量:
class Subclass1 : Parent
{
new static Texture2D pictureOrigin;
Subclass1() : base()
{
picture = pictureOrigin;
}
}
或者,创建抽象方法或类似方法以确保在子类中创建新的静态变量。但这似乎太麻烦而且不太优雅。有没有更好的方法呢?
答案 0 :(得分:1)
你的问题闻起来像是一个糟糕的设计。在我看来,静态变量通常是不好的做法,适当的面向对象设计可以消除使用静态成员的需要。
尝试重构:
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) {
}
}
让我详细说明为什么静态是一个糟糕的选择:
答案 1 :(得分:1)
您可以使用静态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
{
}
用作
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);
}
这是一个例子的调试。它显示SubClass1
自动初始化为pictureForSubClass1
。
答案 2 :(得分:0)
以泛型类型声明的静态成员基本上是按类及其泛型声明的。
例如Foo<Bar>.baz
不等于Foo<Qux>.baz
。
所以基本上您可以这样做:
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");
}