Notes for a course at Linnaeus University: https://coursepress.lnu.se/kurs/objektorienterad-programmering/
This course is unfortunately about C#. Since Linux runs 90 percent of the public cloud workload and 99 percent of supercomputers windowscentric technology seems a tad out of touch with optimality.
Goals:
Essential C# 6.0 by Mark Michaelis and Eric Lippert, ISBN 978-1593275846.
The course has three examinated parts with preparing exercises.
"Education is not received. It is achieved."
Part 1:
Part 2:
Part 3:
C# (see sharp) is a strongly typed object oriented language based on C++ that looks like Java. Code compiles to IL-code which is run in a virtual machine, CoreCLR (Common Language Runtime)
The best way to learn a new programming language is to write code.
using System;
namespace Hello
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
}
}
}
Keywords: abstract, as, base, bool, break, byte, case, catch, char, checked, class, const, continue, decimal, default, delegate, do, double, else, enum, event, explicit, extern, false, finally, fixed, float, for, foreach, goto, if, implicit, in, in (generic modifier), int, interface, internal, is, lock, long, namespace, new, null, object, operator, out, out (generic modifier), override, params, private, protected, public, readonly, ref, return, sbyte, sealed, short, sizeof, stackalloc, static, string, struct, switch, this, throw, true, try, typeof, uint, ulong, unchecked, unsafe, ushort, using, virtual, void, volatile, while, add, alias, ascending, async, await, descending, dynamic, from, get, global, group, into, join, let, orderby, partial (type), partial (method), remove, select, set, value, var, where (generic type constraint), where (query clause), yield
One type declaration per file, the type and file share name.
A static method is called directly from the class name, not an instantiated object.
Variables have block scope.
Data types: bool, byte, sbyte, char, decimal, double, float, int, uint, long, ulong, object, short, ushort, string, void for none
double bar = 2.72;
int foo = (int)bar; // 2
int.TryParse("42", out foo)
bar = double.Parse("273.15");
bar = Convert.ToDouble("273.15");
int[] values = { 1, 2, 3, 4, 5 };
for (int i = 0; i <values.Length; i++)
{
values[i] += 3;
Console.WriteLine(values[i]);
}
foreach (int value in values)
{
value += 3; // Error CS1656 Cannot assign to 'value' because it is a 'foreach iteration variable'
Console.WriteLine(value);
}
int[] values = { 1, 2, 3, 4, 5 };
int[] filtered = values
.Where(x => x % 2 != 0)
.ToArray();
Console.WriteLine(string.Join(", ", filtered)); // 1, 3, 5
var person = new { Name = "Ellen Nu", Age = 6 };
Console.WriteLine($"{person.Name} är {person.Age} år.");
person.Age = 42; // Error CS0200 Property or indexer '.Age' cannot be assigned to --it is read only
person = "Nisse"; // Error CS0029 Cannot implicitly convert type 'string' to ''
Use dynamic as return type to return anonymous types.
Division with integers tosses the remainder.
Modulu operator % works as usual.
9.0=9d
+=, -=, *=, /=, %=
int number;
if (int.TryParse(Console.ReadLine(), out number) &&number % 2 == 1)
{
Console.WriteLine($"Heltalet {number} är udda.");
}
int[] numbers = Enumerable.Range(1, 1000).ToArray();
foreach (int element in numbers)
{
Console.WriteLine(element);
}
Console.WriteLine(element); // Error CS0103 The name 'element' does not exist in the current context
throw new InvalidOperationException("Inte ett udda heltal.");
double number;
try
{
Console.Write("Ange ett flyttal: ");
number = double.Parse(Console.ReadLine());
Console.WriteLine($"Du matade in {number}.");
}
catch (FormatException)
{
Console.WriteLine("Talet är inte i ett korrekt format.");
}
catch (Exception ex) // has to be last
{
Console.WriteLine(ex.Message);
}
finally
{
Console.WriteLine("A finally-block is always executed!");
}
using (var writer = new StreamWriter(@"MyTextFile.txt"))
{
writer.WriteLine("Mats är");
writer.WriteLine("snäll.");
}
using (var reader = new StreamReader(@"MyTextFile.txt"))
{
string line;
while ((line = reader.ReadLine()) != null)
{
Console.WriteLine(line);
}
}
Using using ensures the file is closed even if there is an error.
string json;
using (var reader = new StreamReader("movies.json"))
{
json = reader.ReadToEnd();
}
var movies = JsonConvert.DeserializeObject(json);
Console.WriteLine(string.Join(", ", movies));
Methods and parameters.
Methods are always part of a type, usually a class.
Parameters can have default values and be supplied by name: GetFullName(lastName: "Deer"); // Jane Deer
For variable amount of arguments make last parameter params: static int Sum(params int[] numbers){}
Method signatures have to be unique: methodName(dataType1, dataType2 ...)
Specifying out int number turns it into a reference type, alternatively use ref
Using the dynamic return type is bad practice.
A rectangle has attributes like color and can do operations to change these.
public class Rectangle
{
private int _height;
private int _width;
public Rectangle(int width, int height, Color color)
{
Width = width;
Height = height;
Color = color;
}
public Color Color { get; set; }
public int Width
{
get { return _width; }
set
{
if (value <= 0)
{
throw new ArgumentOutOfRangeException(nameof(value));
}
_width = value;
}
}
public int Height
{
get { return _height; }
set
{
if (value <= 0)
{
throw new ArgumentOutOfRangeException(nameof(value));
}
_height = value;
}
}
public override string ToString()
=> $"Width: {Width}, Height: {Height}, Color: {Color.ToArgb()}";
}
The heap is dynamic memory whereas the stack is static.
Fields "should" be private. The state of the objects consistency is ensured if only the official setters that propagate changes to the whole object are used.
With setters the values of private variables can be restricted, to the great annoyance of developers who want to try something novel. The example of restricting the hour range to 24 hours ensures the code doesn't work for other planets.
Properties are the middle way between public and private.
Simple value types are stored on the stack whereas reference types like classes are stored on the heap.
The CLR allocates memory for classes.
The stack stores a reference to the location of the object in the heap.
A constructorless class has a default constructor that zeroinitializes all fields.
Random random = new Random();
int value = random.Next(1,7);
A die has a value attribute and a throw operation.
public int FaceValue
{
get { return _faceValue; }
set { _faceValue = value; }
}
Don't hardcode a dice max value, there are different kinds of dices.
The first random number of a Random object is determined by system time which may not change in a fast for loop. Therefore dices should have a single persistent Random object that is also seeded by a random number: new Random(seed)
readonly is equivalent to const
Classes, inheritance, base class, derived class, base, override.
Literature chapter 6.
https://github.com/1dv024/example-elementary-inheritance
https://github.com/1dv024/example-great-inheritance
Virtual methods, abstract classes, abstract methods, interface
Literature chapter 6/7
https://github.com/1dv024/example-second-zoo
Privacy leak, deep copy, association
https://github.com/1dv024/example-consoling-association
Examination task 3, stack, queue
Updated on 2020-08-07.