将静态 object 引用存储到 non-static 实例变量中
Storing static object reference into a non-static instance variable
我的目标是在 child classes 中保留静态位图并在基础 class 中使用逻辑,在 child class 中使用最少的代码es.
目前我有 2 个 classes:LEDa
、LEDb
,它们来自 LED
。每个 child classes 都需要它自己的一组 static
objects(巨大的位图)以防止高 ram 使用率。我将 child 位图作为参数传递给基本方法,但我想将 "linking" 代码减少到最少。
我找到了一个 可能的 解决方案,但它看起来很老套,所以我决定征求第二意见。我正在考虑将 child 的静态位图引用传递到基础 class.
的实例变量中
class LED{
Bitmap bmp;
Bitmap[] StateBMP;
int state;
public LED(Bitmap bmp){
this.bmp = bmp;
createStateBMPs();
}
}
class LEDa : LED{ //code is identical in LEDb
static Bitmap bmp = .......;
static Bitmap[] StateBMP;
public LEDa():base(bmp){
}
}
如果我理解正确,初始化 LEDa
和 LEDb
的多个实例只会将 2 个位图加载到内存中,而 LED
中的所有位图将只是链接到 1 个的引用2 个位图中的一个。
我想知道是否有更好的方法来处理这个问题。
我认为您尝试实现的是 Singleton,对此有很多变体,但最简单的解决方案如下所示。
public class LED{
Bitmap bmp;
public LED(Bitmap bmp){
this.bmp = bmp;
}
}
public static class LEDSingleton
{
private static Dictionary<string,LED> LEDs = new Dictionary<string, LED>();
public static LED Instance(string name, Bitmap bmp)
{
if (!LEDs.ContainsKey(name))
{
LEDs.Add(name, new LED(bmp));
}
return LEDs[name];
}
}
然后你这样使用它
var LEDa1 = LEDSingleton.Instance("LEDa", new Bitmap(..));
var LEDb = LEDSingleton.Instance("LEDb", new Bitmap(..));
var LEDa2 = LEDSingleton.Instance("LEDa", new Bitmap(..)); // same instance as LEDa1
注:
而不是 string
名称可以是 enum
或其他名称。
任何 IoC(控制反转)容器在这种情况下都可以很好地工作,因为您可以将 class 配置在 单例范围内 并且每次获得该类型的实例时,都是相同的。
我花了好几个小时尝试不同的方法来实现目标,传递给基础 class 实例对象的静态 bmp 确实有效。我唯一担心的是在 LED
.
的每个实例中都有一个不必要的重复对象引用
根据 Stefan 的回答,我找到了一种方法(不会导致相同的 class 对象具有多个相同的引用)。基本上,子 classes 中的静态位图,可以通过具有覆盖属性的基 class 访问:
class LED{
/*
I used NULL instead of Global.DefaultBitmap, which worked just fine
if you don't leave lose ends, but these classes are actually
Controls and the UserControl test container kept giving me errors
when I scrolled through base control, so I decided to add a static
10x10 image/icon to all base controls to have that instead of errors.
*/
public virtual Bitmap bmp {get {return Global.DefaultBitmap;} set{}}
public LED(){}
}
class LEDa : LED{ //code is identical in LEDb
static Bitmap _bmp;
public override Bitmap bmp{get{return _bmp;}set{_bmp=value}}
public LEDa(){}
}
我的目标是在 child classes 中保留静态位图并在基础 class 中使用逻辑,在 child class 中使用最少的代码es.
目前我有 2 个 classes:LEDa
、LEDb
,它们来自 LED
。每个 child classes 都需要它自己的一组 static
objects(巨大的位图)以防止高 ram 使用率。我将 child 位图作为参数传递给基本方法,但我想将 "linking" 代码减少到最少。
我找到了一个 可能的 解决方案,但它看起来很老套,所以我决定征求第二意见。我正在考虑将 child 的静态位图引用传递到基础 class.
的实例变量中class LED{
Bitmap bmp;
Bitmap[] StateBMP;
int state;
public LED(Bitmap bmp){
this.bmp = bmp;
createStateBMPs();
}
}
class LEDa : LED{ //code is identical in LEDb
static Bitmap bmp = .......;
static Bitmap[] StateBMP;
public LEDa():base(bmp){
}
}
如果我理解正确,初始化 LEDa
和 LEDb
的多个实例只会将 2 个位图加载到内存中,而 LED
中的所有位图将只是链接到 1 个的引用2 个位图中的一个。
我想知道是否有更好的方法来处理这个问题。
我认为您尝试实现的是 Singleton,对此有很多变体,但最简单的解决方案如下所示。
public class LED{
Bitmap bmp;
public LED(Bitmap bmp){
this.bmp = bmp;
}
}
public static class LEDSingleton
{
private static Dictionary<string,LED> LEDs = new Dictionary<string, LED>();
public static LED Instance(string name, Bitmap bmp)
{
if (!LEDs.ContainsKey(name))
{
LEDs.Add(name, new LED(bmp));
}
return LEDs[name];
}
}
然后你这样使用它
var LEDa1 = LEDSingleton.Instance("LEDa", new Bitmap(..));
var LEDb = LEDSingleton.Instance("LEDb", new Bitmap(..));
var LEDa2 = LEDSingleton.Instance("LEDa", new Bitmap(..)); // same instance as LEDa1
注:
而不是
string
名称可以是enum
或其他名称。任何 IoC(控制反转)容器在这种情况下都可以很好地工作,因为您可以将 class 配置在 单例范围内 并且每次获得该类型的实例时,都是相同的。
我花了好几个小时尝试不同的方法来实现目标,传递给基础 class 实例对象的静态 bmp 确实有效。我唯一担心的是在 LED
.
根据 Stefan 的回答,我找到了一种方法(不会导致相同的 class 对象具有多个相同的引用)。基本上,子 classes 中的静态位图,可以通过具有覆盖属性的基 class 访问:
class LED{
/*
I used NULL instead of Global.DefaultBitmap, which worked just fine
if you don't leave lose ends, but these classes are actually
Controls and the UserControl test container kept giving me errors
when I scrolled through base control, so I decided to add a static
10x10 image/icon to all base controls to have that instead of errors.
*/
public virtual Bitmap bmp {get {return Global.DefaultBitmap;} set{}}
public LED(){}
}
class LEDa : LED{ //code is identical in LEDb
static Bitmap _bmp;
public override Bitmap bmp{get{return _bmp;}set{_bmp=value}}
public LEDa(){}
}