Is C# easier to learn than C++?

Constants

Constants are like variables except you can define their value only once. So technically, not variables.

Constants and variables…

— Elizabeth Comstock, Bioshock Infinite

To define a constant:

const <type> name = value;

Like:
const double pi = 3.1416;

Operators

Eh, operators.

Arithmetic Operators

+, -. *, /, … ah I already know them!

Relational Operators

==, !=. >, <, >=, etc.

Logical Operators

Operator Description
&& AND
`
!(condition) NOT

Bitwise Operators

New one! They operate on bits, which means binary operations. Examples are in the source.

Operator Name Description
& AND Copies a bit from both operands.
` ` OR
^ XOR Copies a bit exclusively from either operands.
~ Complement Operator Reverses bits (0 becomes 1 and vice versa). Good for converting negative numbers.
<< Left Shift Pushes bits to the left by a number of bits.
>> Right Shift Pushes bits to the right by a number of bits.

@hhyyrylainen, are they used in Thrive? If they are, which file is it?

And also, when do they become useful?

Skipping assignement operators because they are self-explanatory. As for misc operators, meh. Priority of operators is a long table. I might edit this post, but I don’t know.

Decision Making

if, if else, else if. if else can be replaced by ternary operator like so:

string str = (a >= b) ? "Good." : "Bad.";
Console.Write(str);

Fun fact: If you were to draw a schematics of an else if, you would realize that it looks like a parallel circuit in electronics.

Switch decision making

int num = value;

switch(num)
{
    case 1:
        code;
        break;
    case 2:
        code;
        break;
    case 3:
        code;
        break;
    default:
        code;
        break;
}

Switch statements compare a variable to several values and executes a code accordingly. Otherwise, it executes the default code if specified.

2 Likes

switch statement can also have multiple cases go to the same outcome like this:

int num = value;

switch(num)
{
    case 1:
    case 99:
        code;
        break;
    case 2:
    case 98:
        code;
        break;
    case 3:
    case 97:
        code;
        break;
    case 0:
    default:
        code;
        break;
}
1 Like

I don’t think so. Though, we might use them in the future for packing a bunch of flag bits in a single int, which was used when the game was in C++, but so far there hasn’t been a need to do that in the C# version.

They are useful to manipulate data within individual bytes. Let’s say you wanted toggle the bit at position b in my_byte, you’d do my_byte ^ 1 << b. If b is 2 and my_byte is 0b10101010, you’d get 0b10101110 in this operation (1 << 2 is 0b00000100).

As hhyyrylainen mentioned, it can be used to store or read flags in a header of some file format.
A program reading a file could do something like this (this is in C, going to probably look the same, but I’m just saying it just to be safe in case the code would look different):

// Do stuff if bit 6 is set.
if (flags & 1 << 6) // or (flags & 0b01000000)
  {
    do_stuff()
  }

I don’t really understand what this is but I guess I’ll understand later on.

Ok, so today I’m going to tackle the loops chapter, which is generally the point where I quit learning. Hopefully, I won’t lose my motivation and will go on to learn more. I’m also going to try and create a simple calculator. After that, I may continue learning.

Loops

While Loops

while (a < b)
{
    code;
}

When are they more useful than for loops?

For Loops

for (i = 0; i < 6; i++)
{
    code;
}

do…while Loops

Unlike the while loop, it executes the code right before starting the loop.

do
{
    code;
} while (a < b);

break Statement

The break; statement allows one to terminate a loop, generally when reaching a particular condition (if statement within a loop).

continue Statement

The continue; statement skips the current iteration and goes to the next one.

When you don’t know how many times you are looping, or the condition is a boolean variable, they are the only loop type that makes sense.

I built the calculator.

calculator
program.cs
using System;

namespace Calculator
{
	class Program
	{	
		static void Main(string[] args)
		{	
			double num1, num2;
			num1 = 0.0;
			num2 = 0.0;
			
			while(true)
			{
				Console.WriteLine("This is a calculator. Type 'list' to see all possible operations.");
				string choice = Console.ReadLine();
				
				switch(choice)
				{
					case "1":
						
						Console.WriteLine("You have chosen 'Addition'.\nPlease enter the first number if necessary...");
						/*The user has to enter the numbers first, then the code will take care of the operation.
						If the user has not cleared the previous result, they won't have to enter the first number.*/
						
						Arithmetics addition = new Arithmetics();
						num1 = (num1 == 0.0) ? Convert.ToDouble(Console.ReadLine()) : num1; // if num1 has been cleared, enter the number. Otherwise, keep the same value.
						
						Console.WriteLine("Now, please enter the second number...");
						num2 = Convert.ToDouble(Console.ReadLine());
						
						addition.Addition(num1, num2);
						Console.WriteLine("The result is {0}", addition.result);
						num1 = addition.result;
						
						continue;
					
					case "2":
					
						Console.WriteLine("You have chosen 'Subtraction'.\nPlease enter the first number if necessary...");
						
						Arithmetics subtraction = new Arithmetics();
						num1 = (num1 == 0.0) ? Convert.ToDouble(Console.ReadLine()) : num1;
						
						Console.WriteLine("Now, please enter the second number...");
						num2 = Convert.ToDouble(Console.ReadLine());
						
						subtraction.Subtraction(num1, num2);
						Console.WriteLine("The result is {0}", subtraction.result);
						num1 = subtraction.result;
						
						continue;
					
					case "3":
					
						Console.WriteLine("You have chosen 'Multiplication'.\nPlease enter the first number if necessary...");
						
						Arithmetics multiplication = new Arithmetics();
						num1 = (num1 == 0.0) ? Convert.ToDouble(Console.ReadLine()) : num1;
						
						Console.WriteLine("Now, please enter the second number...");
						num2 = Convert.ToDouble(Console.ReadLine());
						
						multiplication.Multiplication(num1, num2);
						Console.WriteLine("The result is {0}", multiplication.result);
						num1 = multiplication.result;
						
						continue;
					
					case "4":
					
						Console.WriteLine("You have chosen 'Division'.\nPlease enter the first number if necessary...");
						
						Arithmetics division = new Arithmetics();
						num1 = (num1 == 0.0) ? Convert.ToDouble(Console.ReadLine()) : num1;
						
						Console.WriteLine("Now, please enter the second number...");
						num2 = Convert.ToDouble(Console.ReadLine());
						
						division.Division(num1, num2);
						Console.WriteLine("The result is {0}", division.result);
						num1 = division.result;
						
						continue;
					
					case "5":
					
						Console.WriteLine("You have chosen 'Modulus'.\nPlease enter the first number if necessary...");
						
						Arithmetics modulus = new Arithmetics();
						num1 = (num1 == 0.0) ? Convert.ToDouble(Console.ReadLine()) : num1;
						
						Console.WriteLine("Now, please enter the second number...");
						num2 = Convert.ToDouble(Console.ReadLine());
						
						modulus.Modulus(num1, num2);
						Console.WriteLine("The result is {0}", modulus.result);
						num1 = modulus.result;
						
						continue;
					
					case "list":
						Console.WriteLine(" 1-Addition \n 2-Subtraction \n 3-Multiplication \n 4-Division \n 5-Modulus: Find the remainder of a division. \n clear-Clear the previous result. \n exit-Exit the program.");
						continue;
					
					case "clear":
						num1 = 0.0;
						Console.WriteLine("The result has been cleared.");
						continue;
					
					case "exit":
						Console.WriteLine("Please press <Enter> to exit...");
						Console.ReadKey();
						break;
					
					default:
						Console.WriteLine("Wrong input. Please enter a valid input.");
						continue;
				}
				break;
			}
		}
	}
}
arithmetics.cs
using System;

namespace Calculator
{
	class Arithmetics
	{
		public double result;
		
		public double Addition(double number1, double number2)
		{
			result = number1 + number2;
			return result;
		}
		
		public double Subtraction(double number1, double number2)
		{
			result = number1 - number2;
			return result;
		}
		
		public double Multiplication(double number1, double number2)
		{
			result = number1 * number2;
			return result;
		}
		
		public double Division(double number1, double number2)
		{
			result = number1 / number2;
			return result;
		}
		
		public double Modulus(double number1, double number2)
		{
			result = number1 % number2;
			return result;
		}
	}
}

Big brain

However, here’s an interesting message.

Microsoft (R) Visual C# Compiler version 4.8.4084.0
for C# 5
Copyright (C) Microsoft Corporation. All rights reserved.

[justify]This compiler is provided as part of the Microsoft (R) .NET Framework, but only supports language versions up to C# 5, which is no longer the latest version. For compilers that support newer versions of the C# programming language, see Bing

Seriously, this is quite annoying to know that you don’t have the latest version of a language. I just downloaded .NET 5.0, but it didn’t change anything.

3 Likes

It’s probably just the runtime. AFAIK there is a separate development tools you need to download. The Godot mono instructions go into more detail on how to get those development tools without getting visual studio. If you just get visual studio, it comes with everything. Due to the way the C# language is structured, it’s probably very annoying to use the command line to compile projects, so no one uses it directly.

1 Like

I just updated or downloaded Visual Studio 2019 by the way. Any advice?

Encapsulation

There are access specifiers for class data :

  • public
  • private (default)
  • protected
  • internal
  • protected internal

public: Renders a member visible by other classes.
private: Hides a member from other classes, making it accessible only within the same class.
protected: Restrains a member to be accessible only by the same class and its child.
internal: Extends the scope of a member to other classes within the same “application”.
Does it mean within the same namespace?
protected internal: Restricts the scope of a member to the same class and its children only provided that they are within the same “assembly”.

Methods

To define a method:

<access> <return_type> name(parameters)
{
    code;
}

If there is nothing to return, just use void.

public int GetArea(length, width)
{
    return length * width;
}

Also, is there a naming convention for methods? What do you recommend?

To call a method, create the appropriate object if necessary and use the dot syntax.

r.GetArea(2, 7);

You can also call a method within itself, which is a technique called recursion. The website has a good example surrounding factorials. You don’t have to use the dot syntax for recursion.

To pass parameters, there are three ways : by value, reference or output. Value is the default one. Just pass a value as an argument.

int a = 5;
int b = 6;
n.GetArea(a, b);

Reference parameters are another thing. You see, value parameters work by copying the argument’s value into the parameter, which has its own memory location. Reference parameters don’t have to create one because they already refer to another one. Use the ref keyword.

public void swap(ref int x, ref int y) {...}

int a = 340;
int b = 566;

n.swap(ref a, ref b);

Same thing for output parameters, except that the keyword is out and it actually returns the parameter outside the method. So if you define the parameter x as equal to 5 inside the method, you can modify another variable outside the class.

public void getValue(out int x)
{
    y = 5;
    x = y;
}
...
int a;

n.getValue(out a);

/* a is now equal to 5 */

To be continued…

1 Like

This is Microsoft say how to name them:

Here’s another naming convention guide (personally find it easier to read):

1 Like

So when my class has its member variables (fields), I should name them like so?

_fieldName

instead of

fieldName

Nullable Type

Can apparently be assigned any value including null.
Must be declared like this:
<type>? <name> = null;
or
<type>? <name> = new <type>();

There is also the null coalescing operator. It seems shady but it apparently determines which operand to assign to a variable of said type depending on whether the first operand is null. If it’s null, returns the latter. Otherwise, returns the former. It should convert the former to said type if it is not null.

double? a = null;
double? b = 5.46;
double c;

c = a ?? 4.53;
/* c = 4.53 */

c = b ?? 4.53;
/* c = 5.46 */

What’s the purpose of nullables and this operator?

That’s not the style used in Thrive just fieldName is used. We use StyleCop to automatically complain about code that doesn’t follow the naming convention.

It’s used a bunch in Thrive, for example:

src/general/OptionsMenu.cs
698:            var native = Settings.GetLanguageNativeNameOverride(locale) ?? currentCulture.NativeName;
src/microbe_stage/CompoundCloudPlane.cs
123:        material.SetShaderParam("colour2", cloud2?.Colour ?? blank);
124:        material.SetShaderParam("colour3", cloud3?.Colour ?? blank);
125:        material.SetShaderParam("colour4", cloud4?.Colour ?? blank);

It is similar to the ternary operator in that it makes certain type of code more compact.

If you need to denote “no value” as well as numbers, you need a nullable type int? so then you can tell between null and a number. For example in you calculator you assume 0.0 is no number, but that won’t work correctly if the user enters 0. So it’s much better to use double? so you can check if your number is 0 or null.

1 Like

Arrays

Arrays are lists of a fixed size used to store several elements of the same type in a region of memory.

To declare:
int[] arr;

To initialize:
int[] arr = new int[6];

Which way to assign values is more recommended?
  • arr[0] = 1;
  • int[] arr = new int[5] {1, 2, 3, 4, 5};
  • int[] arr = new int[] {1, 2, 3, 4, 5};
  • int[] arr = {1, 2, 3, 4, 5};

0 voters

If you assign an array with another, they will point to the same region of memory. This means that if the former dies, the latter will follow its fate.

To access an element:
int elementA = arr[index];

Another type of loop is the foreach loop. Here’s the syntax:
foreach(int j in arr) {...}
/* int j represents every element of arr. */

Multidimensional Arrays

2D Arrays
int[,] table2D;

3D Arrays
int[, ,] table3D;

2D arrays are like an excel spreadsheet; it’s a table.

int[,] t = new int[3, 4]
{
    {1, 2, 3, 4},       // row 0
    {5, 6, 7, 8},       // row 1
    {9, 10, 11, 12}  // row 2
};
Rows Col 0 Col 1 Col 2 Col 3
Row 0 t[0, 0] = 1 t[0, 1] = 2 t[0, 2] = 3 t[0, 3] = 4
Row 1 t[1, 0] = 5 t[1, 1] = 6 t[1, 2] = 7 t[1, 3] = 8
Row 2 t[2, 0] = 9 t[2, 1] = 10 t[2, 2] = 11 t[2, 3] = 12

Does this have anything to do with graphics (2D or 3D) and spreadsheets?

Jagged Arrays

An array of arrays.
int[][] arr;

int[][] arr = new int[2][] {new int[] {1, 2}, new int[] {3, 4}};
int b = arr[0][1]; // b = 2
arr[0][] arr[1][]
arr[0][0] arr[0][1] arr[1][0] arr[1][1]
1 2 3 4

Does this have anything to do with merging cells in spreadsheet software?

You may also pass an array as an argument. Speaking of arguments, you can use parameters arrays when you don’t know how many parameters you need to pass. Use the params keyword in that case.

public int ArraysPar(params int[] arr) {...}

Skipping Array class because I can go back to it when I need to.

To be continued…

Doesn’t have anything to do with graphics. Though, if you are making a 2D game, you can represent a game area’s map with a 2D array with each cell containing the object that exists in the game world at that location.

Probably not, but I haven’t coded spreadsheet software. I would expect that they use some more complex in-memory notation to make sparse spreadsheets more effective (you can scroll to like row 2 million and add a single value without breaking spreadsheet software).

Or divide each chunk with jagged arrays.

Strings

Just like an array of characters.
string game = "Thrive";

string[] stringArray = {"All", "Hail", "Thrive!"};
string message = String.Join(" ", stringarray);

char[] array = {'O', 'v', 'e', 'r', ' ', 'h', 'e', 'r', 'e', ',', 'J', 'i', 'm', 'm', 'y', '!'};
string decoy = new string(array); // "Over here, Jimmy!"

Properties

Chars - What the hell is this? How do I use it?
Length - Number of characters.

Methods

Too long!

Structures

Value data type. Kind of list holding different variables.

struct Movies
{
    public string director;
    public string main_actor;
    public int duration; // in minutes
};

Are they always defined outside namespaces or classes?

Movies Movie1;

Movie1.director = "Todd Philips";
Movie1.main_actor = "Joaquin Phoenix";
Movie1.duration = 122;

It’s also possible to define methods inside structures.

Enums

List of named integers. Value data type.
enum <name> {list};

enum Months {Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec};

static void Main(string[] args)
{
    int FirstMonth = (int) Months.Jan; // 0
    int LastMonth = (int) Months.Dec; // 11

   ...
}

To be continued…

*double post

I’m starting to see irregularities within the tutorial.

https://www.tutorialspoint.com/csharp/csharp_polymorphism.htm

https://www.w3schools.com/cs/cs_polymorphism.asp

Why do they speak in a so chaotic way?

Where W3Schools explains OOP in a good order, tutorialspoint seems to do everything scrambled.

W3Schools explains ‘virtual’ and ‘override’ way before ‘abstract’. tutorialspoint is trying to explain them all at once. It’s really confusing…

You know what, just this once, I’ll use w3schools chapters in-between.

1 Like

Tutorialpoint is not really organized well, in my experience

It seems like it was organized well at the beginning like you know from Environment to Strings, but Encapsulation should have been moved at the end. Its only advantage is its huge library of tutorials/languages.

Wait, you used it in the past?

I mostly use it when i forgot something like how to make a array or list
It works well for that purpose

2 Likes

Ha! And look at all the text!

Tutorialspoint:

dsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsja

W3Schools be like:

adsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsjadsajlaskj;lsja