As soon as I granted Noname access through the shields of Wonderland, two things changed in my life: I wasn't that lonely anymore, and I became a double agent. On the one hand, humanity believed in me, and I was doing my best to return possession of Earth to humans. On the other hand, I revealed all of Wonderland's network to a machine, and knowing the potential damage that could cause stung a bit. The good thing is that I know what I'm doing. Do I really though? Yes, I suppose I do. This machine is the only sane creature in the world of future.
Noname needed some time to get up to speed on the Rust project. Meanwhile, I investigated Wonderland.
The whole place was quite heavily roboticized. It was both terrific and threatening at the same time. We were essentially using machines to fight other machines. We trained our coding skills on those machines that we had, reprogrammed them, added new modules and updated old ones. That's how we discovered how they are built. Unfortunately, the machines on the other side of the equation, bent on destroying humanity, where producing new versions of their own robots every week. Understanding this highlighted to me the fact that we were simply learning concepts of programming, rather than the machine's software architecture, because that changes far too often to keep up with. The skills involved in becoming a good programmer will help lay the groundwork to allow each of us to grasp a new software construction if needed.
Professions in Wonderland are divided between support and execution roles. The support track is all about supplying resources to Wonderland to make sure everyone has water, food, air, and health care. Execution professions are all about programming to fight machines. Guess which area is more popular. If you're thinking the flashy, high-speed execution track is more popular, think again! Support roles are actually more coveted. Why? Because people don't want to die, first of all. Machines hunt the best programmers the same as the U.S.A. government hunted terrorists at the start of the second millennium. In addition, if executers disappear one day, supporters have the knowledge and skills to survive. The opposite doesn't hold true: if a majority of supporters disappear, it would be difficult for executors to keep it all together and find all resources needed for life. These people are less organized and tired of endless war; above all, they just want to get some rest. No heroes here. They need hope, and I'm here to bring it with me!
Today I had one more lesson with Sintia.
"Hello everyone, sorry for being late," Sintia said as she entered the class.
I had always liked when people with a high status, such as professors, managers, or presidents took a moment to apologize for being late. That small consideration shows how they value the time of other people.
"Today we are going to talk about the static keyword," she said. Taking a sip of water, she began sharing with us all her wisdom.
"Let's start talking about memory. First, we create a class Dog with two fields and a constructor:"
class Dog
{
private string _name;
private int _age;
public Dog(string name, int age)
{
_name = name;
_age = age;
}
}
"How much memory does this take?" Sintia asked.
"It takes nothing because we haven't created any objects yet," answered one of the students, recalling our previous lessons.
"Well, it will still take a very tiny amount of space, but yes, for your level, it's ok to say it takes nothing," Sintia smiled.
She continued, "Next, we create two objects of class Dog , with different names and ages:"
class Program
{
public static void Main()
{
var chappy = new Dog("Chappy", 3); // _name == "Chappy", _age == 3
var lucy = new Dog("Lucy", 5); // _name == "Lucy", _age == 5
}
}
"The memory layout for these objects looks like this:"
Sintia continued, "As you see, both fields are copied for every new object and changing one of them will not impact others. This is where the static keyword comes in. A static modifier declares a static member, which belongs to the type itself rather than to a specific object."
" Static fields. When we mark the field with static , it will NOT be copied every time a new object is created. To make a field static , add the static keyword right after the access modifier, just before the field's type. To access a static field, use a class name instead of the object name. Take a look at the following example:"
class Dog
{
public static int DogsCounter; // public static field
private string _name;
private int _age;
public Dog(string name, int age)
{
_name = name;
_age = age;
DogsCounter++; // Changing the static field
}
}
class ClassWithMain
{
public static void Main()
{
Dog.DogsCounter = 0; // Access static field
var chappy = new Dog("Chappy", 3); // DogsCounter is incremented
var lucy = new Dog("Lucy", 5); // DogsCounter is incremented
Console.WriteLine(Dog.DogsCounter); // Access static field
}
}
// Outputs:
// 2
"Teo, do you understand what is happening in this example?" Sintia asked.
"Well," I said, buying time to get my answer right, "You created a static field DogsCounter and incremented it whenever a new object of type Dog was created".
"Bravo! That is exactly what this code is doing! In the end, DogsCounter contains the number of objects created, and in our case, it is 2," Sintia said.
"You mean it updates the same DogsCounter for every object?" one of the students asked.
"Exactly - take a look at the memory layout to understand it better:"
"As you see, the field is shared among objects if it is marked with static ," Sintia concluded.
"Can you say that static fields belong to a class, rather than to an object?" one of the students asked.
"Yes, you can say so," Sintia answered. She continued:
" Static fields are accessible from within any object of a class, any method, or any constructor. They can also be public or private . Just be aware that when you change the static field from one object, you change it for all other objects as well. "
"Now that we've covered static fields, it's time to talk about static methods. The static keyword applies to methods as well as fields. A static method behaves similarly to a non- static method, but it has access only to static fields and methods and does not require an object of a class to be created. To call a static method, use a class name instead of an object name. To make a method static , add the static keyword after the access modifier.
"I'm sorry, but this is a lot of new information right in a row. Can we just create a static method and see it in action?" someone asked.
"You want everything at once...," Sintia replied "Sure, here is an example:"
class Dog
{
public static int DogsCount; // public static field
public string Name; // public NON-static field
public void NotStaticMethod()
{
DogsCount = 0; // Can access static field, no problem
Name = "Hairy Paw-ter"; // Can access non-static field
}
public static void StaticMethod()
{
DogsCount = 0; // Can access static field, no problem
Name = "Chewbarka"; // Can't access non-static field. Error
}
}
class Program
{
public static void Main()
{
Dog.StaticMethod(); // Call static method on a class. No object
// required.
Dog.NotStaticMethod(); // Can't call non-static method on a class,
// object needed
Console.WriteLine(Dog.DogsCount); // Access static field via class
// name
Console.WriteLine(Dog.Name); // Can't access non-static field
// via class name
var dog = new Dog();
Console.WriteLine(dog.DogsCount); // Can't access static field via
// object
Console.WriteLine(dog.Name); // Can access non-static field via
// object
dog.StaticMethod(); // Can't call a static method on an object.
// Use class name.
dog.NotStaticMethod(); // Can call non-static method on an object
}
}
"Why is the Main method is always static?" I asked.
"I was expecting that question sooner or later," Sintia said. "It is a C# standard. The Main method should always be static . Now that we've gone over static methods, you can probably guess why we've obliged you to declare all methods with static to be able to compile a program?"
"You mean that because Main is static , it can call only static methods?" I answered/asked.
"Exactly right. If you want to call a method from Main without first creating an object, you must make that method static ."
class Program
{
static void StaticMethod()
{
// Something
}
void NotStaticMethod()
{
// Something
}
public static void Main()
{
StaticMethod(); // Ok. Can call static from static.
NotStaticMethod(); // Error. Can't call non-static method like this.
var program = new Program(); // Not standard, but still valid
program.NotStaticMethod(); // Ok. Can call a non-static method on
// an object.
}
}
"Sintia, is it possible to declare a local variable as static ?" someone asked.
"No, C# doesn't support static local variables. However, C# does support static classes as well as static constructors."
"What is the difference between a usual class and a static class?" I asked.
"Well, for one, you can't instantiate a static class. " Sintia began.
"Is instantiating the same as creating an object of a class ?" someone interrupted.
"Instantiate means to create an instance of a class using the keyword new . The process of creating an object of a class is also called instantiating a class ," Sintia explained.
"What was I saying? Ah, right. You can't instantiate a static class, and as a result, the static class can't have any non-static fields, methods, or constructors. Does everyone follow? I see lots of bewildered eyes," Sintia said, smiling and scanning the students in the classroom.
The rapid pace of the class was starting to wear on me and my peers. "I think we're a bit lost," I said. "Sometimes you talk about entities we've never heard of without explanation. For example, we haven't covered what static constructor is, but we know that in a static class all constructors should be static . It would be easier if we knew static constructor was first," I complained.
Sintia stopped smiling. She stared up at the ceiling and tool a three-second pause. Then she came back down to earth with a speech. "You are right, Teo. I will be more cautious in the topic discussions. Having said that, I'm asking each and every one of you to put as much effort as you can into learning outside of class as well as in. The world's fate is in our hands. There is no way back. Only forward. Toward victory!
"Ok, let's try that again," Sintia said, recalibrating. " Static constructors . The main purpose of a static constructor is to initialize static fields , in the same way that the usual constructor initializes instance fields. To create a static constructor, add the static keyword before the constructor declaration. Be aware that static constructors can't have access modifiers, are always parameterless, and have access only to static fields and methods. Here's an example of a static class with a static constructor:"
static class Util
{
private static int _someStaticField;
private static string _anotherStaticField;
private int _notStaticField; // Error: Cannot have non-static fields in
// a static class
static Util() // Static Constructor: Must be parameterless and have no
// access modifiers
{
_someStaticField = 0; // Initializing static fields
_anotherStaticField = "Secret initial value"; // Initializing static
// fields
}
public void DoWhatever()
{
// Error: Cannot have non-static methods in a static class
}
public static void PrintState() // Static Method
{
Console.WriteLine(_someStaticField);
Console.WriteLine(_anotherStaticField);
}
}
"A usual constructor is called when the object is created, but when is a static constructor called?" someone asked.
"A static constructor is called automatically before the first instance is created and before any static members are referenced," Sintia replied.
"Sintia, can a single class have both a static constructor and a usual one?" I asked.
Sintia replied, "Yes, that is an absolutely valid case. As long as the class itself is not static , it is possible. Take a look at this code sample:"
class DroidCleaner
{
private static string _shieldsLockDownKey; // Static field
private string _name; // Non-static field
static DroidCleaner() // Static constructor
{
_shieldsLockDownKey = "02344F70"; // Initializing static fields
}
public DroidCleaner(string name) // Instance (usual) constructor
{
_name = name; // Initializing instance (usual) fields
}
public static void SetNewShieldsLockDownKey(string key) // Static method
{
_shieldsLockDownKey = key; // Only has access to static fields
}
public void PrintName() // Non-static method
{
Console.WriteLine(_name); // Has access to instance fields
}
}