我正在制作一个Color类,并提供一个标准的构造函数
Color(int red, int green, int blue)
然后我想提供一种简单的方法来获得最常见的颜色,如Color.Blue,Color.Red.我看到两种可能的选择:
public static readonly Color Red = new Color(255, 0, 0); public static Color Red { get { return new Color(255, 0, 0); } }
我不完全理解的是,如果有一个优势,而不是静态关键字的工作原理.我的想法是:第一个创建一个实例,然后该实例在程序的整个持续时间内保留在内存中,并且每次调用Red时,都会使用此实例.后者仅在首次使用时创建一些内容,但每次都会创建一个新实例.如果这是正确的,那么我认为如果我提供了很多预定义的颜色,那么第一个会使用大量不必要的内存吗?因此,每次我猜测它是内存使用量与实例化对象的运行时开销.
我的推理是否正确?在设计类和使用static关键字时,对最佳实践的任何建议都会很棒.
我猜你可能已经意识到框架提供了一个Color
结构.我猜你正在Color
为练习创建一堂课.
您对static
关键字的含义表示不确定,尽管您已正确使用它.当static
应用于类或结构的成员时,表示该成员作为整体属于该类,并且不适用于单个实例.静态数据成员(字段)只创建一次; 实例没有自己的副本.在没有实例引用的情况下调用静态函数(方法和属性).
就内存使用情况而言,在你的情况下我不会太担心它.您的Color
类不应该为每个实例使用多个字节(例如,框架的Color
结构在一个32位中存储红色,绿色,蓝色和alpha int
).如果你Color
真的是a class
而不是a struct
,那么你将在开销中有更多的字节(每个实例将有一个额外的32位v-table/typeinfo指针,每个引用是一个额外的32位),但是即便如此,你说每个实例大约12个字节左右.如果预定义了100种不同的颜色,则使用<= 1200字节.真的没什么大不了的.
但是,有懒惰实例化的原因.有些类确实使用了大量的内存,而且有些系统会占用有限的系统资源,有些类需要花费很长时间来构建自己,等等.对于这些类,有时最好使用如下模式:
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
使用struct 时没有堆分配,并且没有v-table或引用指针,所以真正考虑的是你的构造函数需要多长时间.