我猜你可能已经知道框架提供了一个Color 结构。我猜你正在创建一个 Color 类只是为了练习。
您对 static 关键字的含义表示不确定,尽管您已正确使用它。当static 应用于类或结构的成员时,意味着该成员作为一个整体属于该类,并且不适用于单个实例。静态数据成员(字段)只创建一次;实例没有自己的副本。在没有实例引用的情况下调用静态函数(方法和属性)。
就内存使用而言,在您的情况下我不会太担心。您的Color 类不应在每个实例中使用超过几个字节(例如,框架的Color 结构将红色、绿色、蓝色和alpha 存储在一个32 位int 中。)。如果你的Color 是一个真正的class 而不是struct,那么你将有更多的字节开销(每个实例将有一个额外的 32 位 v-table/typeinfo 指针,并且每个引用是一个额外的 32 位),但即便如此,你说的是每个实例大约 12 个字节。如果您预定义了 100 种不同的颜色,您将使用
不过,延迟实例化是有原因的。有些类确实使用大量内存,有些会占用有限的系统资源,有些则需要很长时间才能构建自己,等等。对于这些类,有时最好使用像这样的模式:
class Heavy{
static Heavy first;
static Heavy second;
public static Heavy First{
get{
if(first == null)
first = new Heavy();
return first;
}
}
public static Heavy Second{
get{
if(second == null)
second = new Heavy();
return second;
}
}
}
另一个考虑因素是可变性。您的 Color 类是可变的还是不可变的?换句话说,您的类的实例是否可以更改其值,或者它们是否总是在创建后代表相同的值?
如果您的Color 是可变的,那么拥有静态“红色”访问器的唯一正确方法是您的第二个示例,即每次访问都创建一个新访问器。这样一来,某人就不能做类似的事情:
Color.Red.G = 255;
并使单个共享的 Color.Red 实例实际上代表黄色。
但也请记住,在以下情况下:
for(int y = 0; y < bmp.Height; y++)
for(int x = 0; x < bmp.Width; x++)
if(bmp.GetPixel(x, y) == Color.Red))
MessageBox.Show("Found a red pixel!");
将创建您的Color 类的很多 个实例。当然,它们稍后会被垃圾收集,但这仍然是您上面的第一个构造的案例参数(或我给出的“重”示例)。
现在,如果您的 Color 实际上是一个结构,那么这是一个略有不同的故事。当你 new 一个结构时没有堆分配,也没有 v-table 或引用指针,所以真正考虑的是你的构造函数需要多长时间。