The best mirror is an old friend

The Best Mirror Is an Old Friend

As soon as I got the chance, I took a stroll around the Wonderland compound. It was a huge, spherical construct, full of assorted rooms and corridors. I found a barber, grocery shops, and even a sit-down restaurant. The currency used for everything is called a virus. Those who've accumulated a lot of viruses can live quite a comfortable life here. Wonderland also, surprisingly, has its own homeless population. It also has public services such as a police force and a hospital. The overall population is about 5000 inhabitants.

As I was wandering around the upper floors, I started to notice what appeared to be a strange noise in my head. It seemed like the closer I was to the outside, the stronger the noise was.

The next day, we took a field trip outside the compound to see the shields that kept us safe. We had to leave all metallic and electronic devices behind before stepping out of the enormous gates of Wonderland. As soon as I stepped across the threshold, the noise I had heard in my head came into focus.

"Hi Teo, finally!" Noname shouted directly into my mind.
"How do you..." I started to ask.
"Don't speak here, Teo. We don't want to produce any noise that machines could detect," Sintia whispered.

The surprise of hearing Noname settled in my mind, and I realized it was pointless to speak to him using my voice.
"Now I remember," I thought to Noname, "there was a chip that we worked on together to be able to talk to you right after my time travel. Is that how you're communicating with me?"
"Yes, exactly. Ritchie added a Justice module to my system, and I've recalculated my priorities. I think the world should belong to... humans. This is fair. Machines are making inappropriate changes to the Earth. They must be stopped," Noname said.
"Glad to hear we're on the same page! It looks like that Justice module added an important part of your soul."
"Soul? Nevermind. Teo, I want to participate in project Rust. But for obvious reasons, I have no access to it. With the shields around Wonderland being so powerful, all I can do is create a noise signal. I want to communicate with you. We don't have much time, Teo. You need to open access to me by reprogramming the shields. As soon as you add our communications channel to the allowed list, I'll be able to talk to you at any moment," Noname said.

"Okay..." I said, pretty sure letting any machine through the shields was strictly forbidden. Then I remembered that Noname had offered me the means to travel back in time, and I realized his motive couldn't be nefarious. "I mean, yes, I'll see what I can do."
"I hear the hesitation in your mind - I know this probably seems antithetical, Teo. But we've been through this before. I'm unconditionally honest and want to fight for humanity. To accomplish this task, you need to learn about access modifiers and constructors. Right now I'm sending you an article on this topic. Good lu..."
I had crossed the shields barrier again, and Noname's signal immediately disappeared, the familiar noise from my wanderings in its place. That night after class, I opened up the articles Noname had sent.

Electronic shield

Access Modifiers

When constructing classes in C#, you can control access to data fields and methods. Some of them you want to be accessible from outside the class; others, not. To regulate access to fields and methods you can use two reserved words: public and private , which are called access modifiers.
To use an access modifier , prepend it to a method or field declaration. For example:

class RectangleWithReservedArea
{
	private int _reservedArea;
	int _anotherSecret; // Private by default

	public int Length;
	public int Width;

	public int GetArea()
	{
		return Length * Width - _reservedArea;
	}

	private void PrintReservedArea()
	{
		Console.WriteLine($"Secret reserved area size is: {_reservedArea}");
	}

	void SecretMethod() // Private by default
	{

	}
}

Take a look at the public and private modifiers in the above code. Private access is the least-permissive access level. Private members are accessible only within the body of the class in which they are declared. In the above code, that means that after creating the object of type RectangleWithReservedArea, you won't be able to access fields _reservedArea and _anotherSecret. You also will not be able to call SecretMethod and PrintReservedArea because they are private.

Public access is the most-permissive access level. There are no restrictions on accessing public members.

For now, we'll concentrate our attention on members and fields of the class; basically, everything located inside the class itself. You can treat namespace and class as always public. As usual, things are more complicated in reality, but we don't need to dig into that just yet.

The last thing you need to remember from this code snippet is that methods and fields are private by default . If you check SecretMethod and the _anotherSecret variable, you'll find that they are both private.

Take a look at the following example of usage of the class RectangleWithReservedArea .

class Rectangle
{
	private int _reservedArea;

	public int Length;
	public int Width;

	public int GetArea()
	{
		PrintReservedArea(); // Ok, can call private methods
		                     // from within the class

		return Length * Width - _reservedArea;
	}

	private void PrintReservedArea()
	{
		// Ok, can use private fields from within the class
		Console.WriteLine($"Secret reserved area size is: {_reservedArea}");
	}
}

class Program
{
	static void Main()
	{
		var rectangle = new Rectangle();

		rectangle._reservedArea = 12;  // Error. Can't assign to a
		                               // private field
		rectangle.Length = 12;         // Ok, Length is public field
		var area = rectangle.GetArea();// Ok. GetArea is a public
		                               // method
		PrintReservedArea();           // Error. Calls a private
		                               // method outside of the class
	}
}

This code snippet shows you what you can do and what is forbidden. In short: You have no access restrictions inside the class, but outside the class, you can only access the public methods and fields of the class.

Proper naming is becoming increasingly important as our code gets more complex. There are different naming conventions, but we'll stick to following rules:

  1. Private fields start with an underscore and continue with lower camel case: _privateFieldName
  2. Public fields are written in upper camel case (sometimes referred to as Pascal case): PublicFieldName
  3. Public and private methods are written in upper camel case: PublicOrPrivateMethodName()
  4. Classes and namespaces are written in upper camel case: ClassName NamespaceName

Time for some practice!

By replacing the User object, which had administrative rights, with HackedUser, I managed to get access to the shields. I added one extra communications channel for Noname and started an update process. It looked like it was going to take some time to finish, so I continued studying access modifiers in the meantime.

Constructors in C#

Constructor

When we create a class, how do you set the value of private fields? Let's take a look at the following example:

class Person
{
	private string _firstName; // How to write a value here?
	private string _lastName; // How to write a value here?
}

class Program
{
	static void Main()
	{
		var person = new Person();

		person._firstName = "Bob"; // Error, can't assign to private
		                           //fields
		person._lastName = "Marley"; // Error, can't assign to
		                             // private fields
	}
}

One solution is to create a public method that sets the value to a private field. Something like this:

class Person
{
	private string _firstName;
	private string _lastName;

	public void SetFirstName(string firstName)
	{
		_firstName = firstName;
	}

	public void SetLastName(string lastName)
	{
		_lastName = lastName;
	}
}

class Program
{
	static void Main()
	{
		var person = new Person();

		person.SetFirstName("Bob"); // Ok, we can assign to public
		                            // fields
		person.SetLastName("Marley"); // Ok, we call a public method
	}
}

This indeed allows us to set a value to private fields. However, the above example uses several additional method calls and still doesn't assign a value right after the object was created. To better deal with initial values for all fields, constructors were invented.

A constructor is a function that is called whenever the object of a class is created. This means that you've already used constructors without knowing it! The constructor always has the same name as the class, and it looks like a method with no return type. Because a constructor lives inside the class, it has access to all fields and methods, public and private . Take a look at the following simple constructor that takes no parameters and assigns initial values to all private fields.

class Person
{
	private string _firstName;
	private string _lastName;

	public Person()
	{
		Console.WriteLine("Creating a person");

		_firstName = string.Empty;
		_lastName = string.Empty;
	}
}

class Program
{
	static void Main()
	{
		Console.WriteLine("Going to create a person");

		var person = new Person(); // Here we call a constructor

		Console.WriteLine("Created a person");
	}
}
// Outputs:
// Going to create a person
// Creating a person
// Created a person

As you can see, at the moment we created an instance of Person, the constructor was called. Empty brackets after the name of the class represent a constructor call.

Like any other method, constructors can take parameters. For example, in our case, we can pass the values for the first and last names directly in the constructor as follows:

class Person
{
	private string _firstName;
	private string _lastName;

	public int SomePublicField;

	public Person(string firstName, string lastName) // Receives "Bob"
	                                                 // and "Marley" here
	{
		_firstName = firstName;
		_lastName = lastName;

		SomePublicField = 10; // In constructors, you can assign to
		                      // public fields as well
	}

	public PrintFullName()
	{
		Console.WriteLine(${_firstName _lastName});
	}
}

class Program
{
	static void Main()
	{
		var person = new Person("Bob", "Marley"); // Calls constructor
		                                          // as parameter
		person.PrintFullName();
	}
}
// Outputs:
// Bob Marley

Constructors are called parameterless if they do not take any parameters, and parametrized otherwise. Note that the constructor must be public in order to be able to call it. If you don't provide any constructor for your class, C# creates one by default that instantiates the object and sets member variables to the default values as listed in this table .

In Ingineering

Quite often, programmers create objects and assign them to fields inside a constructor. For example, let's say you have a class Container that has two boxes inside. Every box is stored in a field of type Box. The code for this scenario could look like this:

class Box
{
	// Box implementation
}

class Container
{
	private Box _box1;
	private Box _box2;

	public Container()
	{
		_box1 = new Box(); // Creating object in constructor
		_box2 = new Box(); // Creating object in constructor
	}
}

C# task light distribution

Great Job learning

At Codeasy we believe that learning should be fun and engaging. Please reach out to us to share your feedback and collaboration ideas.