Skip to content
UoL CS Notes

Introduction to C#

COMP282 Lectures

C# is a fully managed language (like Java). Memory is garbage collected and the compiler handles the allocation of resources automatically.

Hello, world!

A hello world program would look something like so:

using System;
class Hello {
	static void Main(string[] args) {
		Console.WriteLine("Hello World!");
	}
}

Getters & Setters in C#

Getters and setters are used like so in C#:

class Person {
	private string _name;
	public string Name {
		get {
			return _name;
		}
		set {
			_name = value;
		}
	}
}
class Program {
	public static void Main(string [] args) {
		Person p = new Person();
		p.Name = "Charles";
		System.Console.WriteLine(p.Name);
	}
}

It is convention that private variables start with _.

private Getters & Setters

Using one of these outside of the scope of the class will result in a compilation error:

class Person {
	private string _name;
	public string Name {
		private get {
			return _name;
		}
		private set {
			_name = value;
		}
	}
}

Interfaces in C#

C# has interfaces like in Java. We can make and use them like so:

using System;
class Program : IBla {
	static void Main(string[] args) {
		Console.WriteLine("Hello World!");
	}
}
interface IBla {
	bool test();
}

Inheritance in C#

Inheritance in C# is similar to in C++:

using System;
class Program : Bla {
	static void Main(string[] args) {
		Console.WriteLine("Hello World!");
	}
}
class Bla {
	public bool test() {
		return true;
	}
}

Constructors in C#

Constructors look like so in C#:

using System;
class Program : Bla {
	public Program(int b) : base(b) {}
	public Program() : this(0) {}
}
class Bla {
	public Bla(int a) {}
}
  • base is used to refer to the class we inherit (Bla).
  • this is used to refer to the current class (Program).

Inheritance & Interfaces in C#

We can declare both interfaces and inheritance at once:

using System;
class Program : Bla, IBla {
	static void Main(string[] args) {
		Console.WriteLine("Hello World!");
	}	
}
interface IBla {
	bool test();
}
class Bla {
	public bool test() {
		return true;
	}
}

The class must be listed before any interfaces.

Polymorphism in C#

Polymorphism is similar to C++:

using System;
class Program : Bla {
	public override bool test() {
		return false;
	}
}
class Bla {
	public virtual bool test() {
		return true;
	}
}

Our methods can be set in three ways:

  • Using both virtual and override:
    • This will override as expected.
  • Without virtual or override:
    • This will take the function of the parent.
  • With both abstract:
    • This works similarly to in Java.

Access Modifiers in C#

We have the standard access modifiers:

  • public
  • private
  • protected

We also have access modifiers that are used to inform that creation of .dll files:

  • internal - Only from the same compilation.
    • If you compile to a .dll or .exe file, you can only access these from .cs files used to compile it.
  • protected or internal - From the same compilation or from children.
  • protected internal - From children in the same compilation.

Overloading in C#

Generally people don’t overload operators - instead of overloading + we make use add(). This will be shown anyway.

Requirements:

  • Operator overloading must be defined in a class that defines one of the parameters.
  • It must be public and static (meaning call-able from outside an object).
using System;
class Fraction {
	int n;
	int d;
	public Fraction(int n, int d) {
		this.n = n;
		this.d = d;
	}
	public static Fraction operator +(Fraction a) {
		return a;
	}
	public static Fraction operator +(Fraction a, Fraction b) {
		return new Fraction(a.d*b.n + b.d*a.n,a.d*b.d);
	}
}

If we overload true we must also overload false.

Templates (Generics) in C#

We can use generics like so:

class Pair<T,U> {
	public T first { get; private set; }
	public U second { get; private set; }
	public Pair(T t, U u) {
		first = t;
		second = u;
	}
}

File $\rightarrow$ Class Correspondence

In C# you can have any number of files per class and any number of classes per file.

It is preferred to still have one class per file.

To use multiple flies for one class, you need to add the keyword partial in front of class.

Types

All types in C# are objects we can use int and string as shorthand for their full class name.

You can see the full list of types here: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/built-in-types.

STL in C#

In C# we have many collection types:

  • Array
  • List
  • SortedDictionary
  • SortedSet
  • LinkedList

foreach

We can iterate over all the items in a collection with the following structure:

foreach (var x in xs)

LINQ

LINQ is a query language in C#. We can use is like so:

using System;
using System.Linq;
using System.Collections.Generic;
class Program {
	public static void Main(string[] args) {
		string[] names = { "Birgit", "Brian", "Victor", "Finn", "Denise" };
		IEnumerable<string> bnames = //query variable
			from name in names //required
			where name.Substring(0,1)=="B" // optional
			orderby name descending // optional
			select name; //must end with select or group
			foreach (var name in bnames) Console.WriteLine(name);
	}
}

Max() in C#

We can calculate a maximum value using LINQ:

using System;
using System.Linq;
using System.Collections.Generic;
class Program {
	public static void Main(string[] args) {
		string[] names = { "Birgit", "Brian", "Victor", "Finn", "Denise" };
		Console.WriteLine(names.Max());
	}
}

Distinct() in C#

using System;
using System.Linq;
using System.Collections.Generic;
class Program {
	public static void Main(string[] args) {
		string[] names = { "Birgit", "Brian", "Victor", "Finn", "Denise" };
		foreach (var name in names.Distinct()) Console.WriteLine(name);
	}
}

Shuffle with orderby

We can implement a shuffle by sorting at random:

using System;
using System.Linq;
using System.Collections.Generic;
class Program {
	public static void Main(string[] args) {
		string[] names = { "Birgit", "Brian", "Victor", "Finn", "Denise" };
		Random rng = new Random();
		IEnumerable<string> scoreQuery = //query variable
			from name in names //required
			orderby rng.Next() // optional
			select name; //must end with select or group
			foreach (var testScore in scoreQuery) Console.WriteLine(testScore);
	}
}