- Creating Classes
- Creating Objects
- Using Access Modifiers
- Creating Fields and Using Initializers
- Creating Methods
- Creating Properties
- Read-only Properties
- Creating Constructors
- Creating Structs
- Creating Static Members
- Creating Static Fields
- Creating Static Properties
- Creating Destructors and Handling Garbage Collection
- Overloading Methods
- Overloading Operators
- Creating Namespaces
- In Brief
Creating Static Fields
A static field is a class field, which means that its data is stored in one location in memory, no matter how many objects are created from its class. In fact, you can use a static field to keep track of how many objects have been created from a particular class. To do that, you might declare a static field, which we'll name numberOfObjects in the example, and increment that field each time the class's constructor is called (an explicit initializer is required for static fields, so we've assigned numberOfObjects the value 0 here):
public class CountedClass { public static int numberOfObjects = 0; public CountedClass() { numberOfObjects++; } }
Now each time a new object of this class is created, numberOfObjects is incremented. You can see how this works in ch03_07.cs, Listing 3.7, where we create three new objects and display the value of the class's numberOfObjects field each time.
Listing 3.7 Creating a Static Field (ch03_07.cs)
class ch03_07 { static void Main() { System.Console.WriteLine("Number of objects: {0}", CountedClass.numberOfObjects); CountedClass object1 = new CountedClass(); System.Console.WriteLine("Number of objects: {0}", CountedClass.numberOfObjects); CountedClass object2 = new CountedClass(); System.Console.WriteLine("Number of objects: {0}", CountedClass.numberOfObjects); CountedClass object3 = new CountedClass(); System.Console.WriteLine("Number of objects: {0}", CountedClass.numberOfObjects); } } public class CountedClass { public static int numberOfObjects = 0; public CountedClass() { numberOfObjects++; } }
Here's what you see when you run ch03_07.cs. As you can see, the class field numberOfObjects was incremented each time we created a new object:
C:\>ch03_07 Number of objects: 0 Number of objects: 1 Number of objects: 2 Number of objects: 3
Although for the sake of brevity in this example, we made numberOfObjects a public static field, it's usually not a good idea to make class fields public. Instead, you can use an accessor method, but if you do, make sure that it's declared static, as are the methods we'll see next.
Creating Static Methods
As we've discussed, when you have a static method, you don't need an object to call that method; you use the class name directly. You may have noticed, for example, that we used the System.Math.Sqrt method to find square roots and calculate the value of a complex number's magnitude in Listing 3.6; this is a static method of the System.Math class, and it's made static so you don't have to go to the trouble of creating a System.Math object before calling that method.
Let's see an example in which we can create our own static method. Although the System.Math class has a handy Sqrt method for calculating square roots, it doesn't have a method for calculating quad roots (fourth rootsthe square root of a value's square root). We can correct that glaring omission by creating a new class, Math2, with a static method named QuadRt, which returns quad roots like this:
public class Math2 { public static double QuadRt(double value) { return System.Math.Sqrt(System.Math.Sqrt(value)); } }
Now you can use the QuadRt method with the Math2 class directly, no object needed, as you see in ch03_08.cs, Listing 3.8.
Listing 3.8 Creating a Static Method (ch03_08.cs)
class ch03_08 { static void Main() { System.Console.WriteLine("The quad root of 81 is {0}", Math2.QuadRt(81)); } } public class Math2 { public static double QuadRt(double value) { return System.Math.Sqrt(System.Math.Sqrt(value)); } }
Here's what you see when you run ch03_08.cs:
C:\>ch03_08 The quad root of 81 is 3
Note that because static methods are not part of an object, you cannot use the this keyword in such methods. It's important to know that static methods cannot directly access non-static members (which means, for example, that you cannot call a non-static method from a static method). Instead, they must instantiate an object and use the members of that object to access non-static members (as we saw when creating methods called from Main in Chapter 2).
Classes With Only Static Members
As part of programming teams, I've sometimes had to create utility classes, like the System.Math class, which only have static members. In that case, it's best not to allow objects to be created from that class (for one thing, in C#, none of your static members could be called such an object anyway). In these cases, I gave the utility classes a private constructor, which stops the creation of a default constructor, making sure no objects can be created from the class. When you're creating code for general distribution, it's always wise to think of worst-case scenarios. If your code can be used the wrong way, someone will do it.
Creating Static Constructors
You can also make constructors static, like this:
public class CountedClass { public static CountedClass() { . . . } }
Static constructors are called before any objects are created from your class, so you can use them to initialize the data in standard constructors, if you like. C# makes no promise when a static constructor is called. All you know is that it'll be called sometime between the beginning of the program and before an object is created from your class.
Static constructors are also called before any static members in your class are referenced, so you can use them to initialize a class (not just an object). Note that static constructors do not take access modifiers or have parameters.