I'm guessing that you're probably already aware that the framework provides a Color
struct. I'm guessing that you're creating a Color
class just for practice.
You expressed uncertainty about the meaning of the static
keyword, although you've used it correctly. When static
is applied to a member of a class or struct, it means that that member belongs to the class as a whole, and does not apply to individual instances. Static data members (fields) are created only once; instances do not get their own copies. Static functions (methods and properties) are called without an instance reference.
As far as memory usage goes, I wouldn't worry too much about it in your case. Your Color
class shouldn't use more than a few bytes per instance (for instance, the framework's Color
structure stores red, green, blue, and alpha in one 32-bit int
.). If your Color
is a really a class
instead of a struct
, then you'll have a few more bytes in overhead (each instance will have an additional 32-bit v-table/typeinfo pointer, and each reference is an additional 32-bits), but even so, you're talking about 12 bytes or so per instance. If you have 100 different colors predefined, you'll use <= 1200 bytes. Really no big deal.
There are reasons for lazy-instantiation, though. There are classes that do use a lot of memory, and ones that hold on to limited system resources, and ones that take a long time to construct themselves, etc. For these classes it's sometimes better to use a pattern like:
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;
}
}
}
Another consideration is mutability. Is your Color
class mutable or immutable? In other words, can instances of your class have their value changed, or do they always, once created, represent the same value?
If your Color
is mutable, then the only correct way to have a static "Red" accessor would be your second example, where you create a new one every access. That way someone can't do something like:
Color.Red.G = 255;
and make the single shared Color.Red instance actually represent yellow, instead.
But also keep in mind that in a case like:
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!");
A lot of instances of your Color
class are going to be created. They'll be garbage collected later, of course, but this is still a case argument for your first construct above (or the "Heavy" example I gave).
Now if your Color
is actually a struct, then it's a slightly difference story. There's no heap allocation when you new
a struct, and there's no v-table or reference pointer, so the real consideration is then just how long your constructor takes.