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
}
}