CSharp (C#)

CSharp or C# is a relatively modern object-oriented programming language introduced and maintained by Microsoft πŸͺŸ.

It's used by Microsoft .NET framework πŸ’», the Unity game engine for game development πŸ•ΉοΈ, and some web applications 🌍.

Where to learn? πŸŽ“

You can either download and use VSCode, or use another IDE such as Rider. You may use neither and use dotnet from the command line.

PS> mkdir project && cd project
PS> dotnet.exe new console # init a .NET console app
PS> dotnet.exe build       # generate bin
PS> dotnet.exe run         # generate bin
Hello, World!

To get started, edit Program.cs.


Core knowledge

Variables

string variable1;       // explicit type
string variable2 = "";  // default value
var variable3 = "";     // implicit type

Types

Here are some C# types:

int xxx = 42;             // Int32
float xxx = 21f + 21F;    // Single
double xxx = 21.0 + 21d;  // Double
bool xxx = true || false; // Boolean
char xxx = 'c';           // Char
string xxx = "xxx";       // String

To declare a nullable-type 🧨, e.g., explicitly allowing the variable to be null, add ? after the type. When using a nullable variable, we will have a reminder that the variable may be null.

int? xxx = 42;  // may be null

➑️ To suppress the warning, use !, e.g., xxx!.Something.

Print some text in the terminal

Console.WriteLine("Hello, World!");
Console.WriteLine("Hello, " + variable + "!");

Operators

Here is a list of most operators.

int sum = 5 + 5;          // 10
int subtraction = 5 - 5;  // 0
int product = 5 * 5;      // 25
int division = 6 / 5;     // 1
x += 1;                   // same as x = x + 1
x++;                      // same as x = x + 1
// see also: --, -=, *=, and /= 
// logical
if (5 == 5) {}         // true ⚠️ see also "Object#equals"
if (5 != 5) {}         // false
// see also: >, >=, <, <=
if (!false) {}         // logical NOT => true
if (true || false) {}  // logical OR => true
if (true && false) {}  // logical AND => false
if (true ^ false) {}   // logical XOR => true

string t = ""+5;       // concatenation (+cast), see String

Control-flow structures

Branching

Usual if/else.

if (true) {} 
if (true) {} else {}
if (true) {} else if (false) {} else {}

Ternary operator: condition ? value_if_true : value_if_value.

string value = true ? "true" : "false";

Loops

In every loop, you can use break to exit the loop, and you can use continue to end the current iteration, and process to the next one.

// usual loop - i in [0, 10[
for (var i = 0; i < 10; ++i) {}
// reverse loop - i in ]0, 10]
for (var i = 10; i > 0; i--) {}
// nested loop
for (var i = 0; i < 5; ++i) {
    for (var j = 0; j < 5; ++j) {}
}
while(true) {}; // repeat while true
do {} while(true); // executed at least once

Classes

Usually, each C# class is usually in a separate file, while the filename doesn't necessarily dictate the name of the class defined within it.

public class ClassNameHere {}

Namespaces

To make things cleaner, we usually use namespaces to group classes. A namespace is roughly equal to a folder.

namespace Memorize.Code; // ./Memorize/Code/Test.cs

public class Test {}

Aside from default classes, every other class must be imported:

using Memorize.Code;

var test = new Test();

Visibility

Each class/attribute/method/... has a visibility modifier determining who can use a method/access an attribute/...

➑️ By default, everything is private.

Attributes

private string _attribute;
public string Name { get; private set; }
public string Name { get;; }

Method

private void Xxx() {}
private void Yyy()
{
    Xxx(); // same as this.Xxx();
}

Inheritance

C# implements inheritance similarly to Java. Classes can have one parent, and implement multiple interfaces.

public class Parent
{
    public Parent() {}
}

public class Child : Parent
{
    public Child() : base() {}
}

Override

Child classes can override a method, e.g., change the inner code of a method that was declared within their parent.

The child class uses base to reference the parent class.

We can only override a virtual method.

// in the parent
protected virtual void XXX() {}
// in the inheritor - you can change the code
protected override int XXX() {
    return base.XXX(); // default behavior
}

πŸ‘» To-do πŸ‘»

Stuff that I found, but never read/used yet.

  • Nuget packages
  • NUnit
  • Linq
  • C# Cheatsheet
  • Switch (v switch { y => g, _ => d}), foreach
  • [Serializable]
  • sealed override/static
  • is type/as type
  • where X : struct, new(), ...
  • typeof/nameof/using (){}/Func<return, arg1>
  • () => { return z; }
  • private void XXX<T>(T xxx)
  • throw new NotImplementedException();
  • IEnumerator, yield break/return null
  • struct, return default;, string.IsNullOrEmpty
  • new List<>(); Find Add { null } Exists ForEach
  • public static void XXX<ZZZ>( this YYY<ZZZ> caller ) where ZZZ : struct
  • IReadOnlyList
public string Name { get { return _name; } set { _name = value; } }
public string Name { get => _name; set { _name = value; } }
public string Name { get => _name; init => _name = value; }
public string Name { get; private set; }
public class XXX
{
    public static bool operator ==(XXX a, XXX b)
    {
        return false;
    }

    public static bool operator !=(XXX a, XXX b)
    {
        return false;
    }
}