Hello, Wonderland

I arrived in Wonderland yesterday. I'm still not entirely sure that my decision to stay in the future was wise... In any event, I'm comfortable with where I'm at now. I carry more responsibility and have mostly stopped lamenting my hardships.

Infinity gave me a quick briefing about the situation here. Wonderland is the largest-known resistance base on Earth. It's surrounded by a shield that prevents machines from scanning the area. Instead of analyzing the surface for the base, the machines have resorted to brute-force tactics, namely digging, in hopes of hitting the jackpot. Because of this, the atmosphere here is tense: people are afraid that at any moment the machines may come up out of the ground and reveal Wonderland's location.

The primary objective for everyone here is a project codenamed Rust , which is a virus that provides full control over a machine to any chosen server. In our case, of course, that would mean a resistance server. We want to inject this virus in the handshake message that every device sends to one another when they establish communication. So far, so good - prototypes of virus already exist! But... they don't work. That's why I'm here, and why Infinity gathers the best programmers from other resistance bases. She needs this virus to work. As soon as possible.
While humanity still has some fight left in it.

There are a lot of small details that need to be sorted out in order for Rust to work; for example, if we can take control of a machine, how do we send commands to billions of machines at once? One server won't be able to control that amount of traffic, and if that server crashes, we immediately lose our advantage. The machines will quickly craft an antivirus. In addition, there are probably ten new machine prototypes produced every single week - how can Rust adapt to that kind of variety? I know, I know, not exactly positive thinking. But this is the best option we have for now, and we will; rather, we need ; to solve all of it.

The skill level of the programmers in Wonderland is astounding. I feel like a freshman again, and I will doubtless have studies every day as before. Let's get started!

Welcome to the Class !

The main instruction room was bigger and brighter than the one in Ritchie's resistance base. Ten students were here with me. The teacher was a woman, around 35-40 years old, with big glasses.
"Hello everyone! My name is Sintia, and we are going to have a brief overview of classes today. Let's make a list of what you learned before you came to Wonderland," she said, picking up a marker.
We named some topics in C#, and everyone's answers were fairly similar. Apparently, in all the resistance bases, people know the same subset of C#.
"Ok, that's a good start," Sintia said. "But these are only basics. Your real education in C# starts today, now, in this room. Can anyone tell me where the concept of classes came from?"
This time, no hands went up.
"Ok then, here's the origin story. A long time ago in a language called C , there were no classes or namespaces; people were writing functions, and everything just worked. As software development grew, however, programs became more and more complicated. Eventually, name clashes started to occur when several functions with the same name were imported from different programming modules. This made it impossible to compile the code. Imagine a simple scenario where you have a game with a Log(string message) function to write something to a log file. And then a module gets imported that also has its own Log(string message) function. As you all know, you can't have two functions with the name Log, because they'll be indistinguishable from one another. That's why programmers began to create prefixes, like Internal_Log(...) and ExternalLibName_Log(...) . The same was done with global data variables: int Internal_Timeout , int ExternalLibName_Timeout , etc. As a result, code became longer, less readable, and more difficult to write. That's why smart people decided to bring into C the concept of an object - an entity that stores data and the methods to work with that data all in one place. This entity will also determine a scope, which means methods and variables with the same name can exist in different entities."

The paradigm of using objects is called OOP - object-oriented programming. Object-oriented programming (OOP) is a programming paradigm based on the concept of "objects," which may contain data fields and code, in the form of procedures, often known as methods.

Programmer's hell

"Can I ask you a question?" I said.
"You already did," Sintia answered with a light smile on a face.
"Why did you start talking about classes but then switch to objects ? Are they the same thing?" I wondered.
"Good question, Teo! Nice catch!" she looked satisfied.
"A class is a template for objects. A class defines object properties including a valid range of values and a default value. A class also describes object behavior. An object is an "instance" of a class. An object has a state in which all of its properties have values that you define. "
"Sorry, but I don't understand," said another student. "Can you show us an example?"
"Fair enough. Look at this class definition:"

class Box
{
  int Length;
  int Width;
  int Height;
  bool IsOpened;

  public void Open()
  {
    IsOpened = true;
  }

  public void Close()
  {
    IsOpened = false;
  }
}

"Why didn't you use a static keyword for the methods? All the methods we worked with before now were static ," another student asked.
"Yeah, this can be confusing," Sintia answered. "Please, until you learn what static means, leave only the Main method as static ; all other fields and methods should not have a static modifier."

Sintia continued:
"Can anyone tell me how much space in memory the Box class occupies now?"
"An integer is 4 bytes, which means we need three multiplied by four and add..." one of the students began thinking out loud.
"Wrong. It takes 0 bytes. What you see is only a template of a box that could be created . But there are no boxes created in this code - what you see is a class . Remember, a class is only a template for a real instance. It shows you what an instance of that class will look like, but it does not create an instance. Think of a class name as a new type like int or string . After you've created the Box class, you can create variables of type Box and assign values to them, " Sintia concluded.
"How can I create an instance of a box?" I asked.
"In a Main method, use the new operator, as you did for arrays."

Box boxObject = new Box();

"Now, boxObject will take some space in memory, because it is an object, not just a class ."
"I think I understand now. An object is something real, that is allocated in memory, and we can control it during program runtime. A class is just a template for all objects that are going to be created ," said one of the students.
"Yes, exactly!" Sintia looked satisfied.
She continued, "A class consists of fields (members) and methods. Fields (or members) are for storing the typed data, the same as local variables. Methods are functions that work with this data. You can access all fields from within methods of the same class; again, the same as you did with local variables. Here's a figure that might make it a bit more clear."

C# class structure

"Any final questions before we delve into the practice of objects?" she asked.
"What types can you use for fields?" asked someone in the back.
"Any type that you want. It can be a string , array , double , Box , or any other type. If you want a deeper dive into fields, you can read this article, which I'll post in the notes. Time for the first exercise!"

C# joke best code in the world

"Sintia, how do I assign a value to a field from outside of the class ? For example, say I want to create a user with a name 'Bob'?" asked one of the students.
"Good question! There are several ways of working with fields. I'll show you the simplest one; you'll learn others along the way. First of all, you need to modify fields in the User class to make them public . You'll learn more about access modifiers in the future, but for now, you just need to know that public methods and fields are accessible from outside of the class, like this:"

class User
{
  public string Name;
  public int Age;
}

"To assign a value to a public field from outside of its class, you need to type an object name, then dot(.), and then the name of the field. Then assign a value to it like normal. Here is an example: "

class User
{
  public string Name;
  public int Age;
}

class ProgramWithMain
{
  public static void Main()
  {
    // Classic approach
    User bob = new User();
    bob.Name = "Bob";
    bob.Age = 38;

    // And an "object initializer" version
    User anotherBob = new User
    {
      Name = "Bob",
      Age = 38
    };
  }
}

"Do I understand correctly that you've created two objects of the same class ?" I asked.
"Yes, Teo," Sintia answered. "To be even more precise, I've created two objects of type User inside the Main method. Main is located outside of the User class - that's why you can't use Name or Age directly. They belong to another entity. Thus, first, we create that entity. Remember, to create an object, first enter its type followed by your name for the new instance, then 'equals', followed by the new keyword, and then the type name again followed by a set of parentheses."

User bob = new User(); // Created an object bob of type (class) User
User alice = new User(); // Created one more object of type (class) User
User sam = new User // Created an object of type User with object initializer
{
    Name = "Sam",
    Age = 12
};

"What is an object initializer?" someone asked.
"Good eye!" Sintia replied. "It's another way of creating an object - more 'modern' or C-sharpish. You can also use var instead of the type name. In the following table, every code snippet does absolutely the same thing:"

Classic Object Creation

Object Initializer

User user = new User();
user.Name = "Bob";
user.Age = 38;
User user = new User
{
  Name = "Bob",
  Age = 38
};
var user = new User();
user.Name = "Bob";
user.Age = 38;
var user = new User()
{
  Name = "Bob",
  Age = 38
};

"Are you ready to use objects? Or is there maybe something you're still missing?" Sintia asked.
"If you are asking, then we are still missing something," I said, smiling.
"You got it Teo. You'd be a good psychologist! But you're a programmer here; turn on your logic. What are you missing?" Sintia sounded serious.
Logic turned on. "Well, I know how to declare a class, create an object, set all fields of this object ... Wait, how do I access them?"
"Bingo! You need to access fields. To do it, just use the syntax of the assignment, but don't assign any values. Type the object name, then a dot(.), followed by the name of a field. Be aware that this only works for public fields. "

var user = new User
{
  Name = "Sam",
  Age = 12
};
Console.WriteLine($"Hello, {user.Name}");
Console.WriteLine($"You are so young, only {user.Age} years old!");

user.Age++; // Work with fields like with local variables before
Console.WriteLine($"{user.Name}, now your age is changed to: {user.Age}.");

user.Age = 15; // Work with fields like with local variables before
Console.WriteLine($"{user.Name}, now you are {user.Age} years old.");

// Output:
// Hello, Sam
// You are so young, only 12 years old!
// Sam, now your age is changed to: 13.
// Sam, now you are 15 years old.

"To pass objects to methods as parameters, you can do the same as you did for arrays; i.e., pass the objects in by reference."

class User
{
    public string Name;
    public int Age;
}

class NamePrinter
{
    public void PrintNameNicely(User user)
    {
        Console.WriteLine($"!!!### {user.Name} ###!!!");
    }
}

class ClassWithMain
{
    public static void Main()
    {
        var bob = new User // Created an object of type User
        {
            Name = "Bob",
            Age = 12
        };

        // Created an object of type NamePrinter
        var namePrinter = new NamePrinter();

        // Passed an object bob to a method of another object
        namePrinter.PrintNameNicely(bob);
    }
}