C# Essential Training 1: Types and Control Flow
Link
https://www.linkedin.com/learning/c-sharp-essential-training-1-types-and-control-flow/
Course notes from LinkedIn Learning.
Explore the essentials
What you should know
C# compiles to MSIL
- All .NET languages compile to Microsoft Intermediate Language (MSIL), also known as “managed code”.
- Therefore the language can evolve independent of the runtime (i.e. developers can benefit from new constructs in [[C Sharp|C#]], while the compiled code stays compatible with the already installed runtime).
- .NET 6 was released in the fall of 2021.
.NET runtime is responsible for running MSIL
- The runtime can be installed separately from the SDK, similar to how Java can be installed as either the JRE or JDK.
- More recent versions of the runtime allow it to be deployed together with the application, not requiring a system-wide installation as earlier.
- Thus applications targeting different runtime versions can co-exist on the same machine.
The base class library
NuGet packages
Compiling C# to a library or executable
- The command-line compiler is called
csc.exe
.
Understanding classes, structs, and records
- Some compiler options (“flags”) can be set in the
*.csproj
file. - C# language versioning
- Starting in .NET 6, reference types (e.g. objects, including strings) are not nullable by default for new projects.
- Any type (reference or value) can be allowed to be nullable by declaring it with a question mark, e.g.:
string? name;
- All implicitly typed local variables (declared using
var
) are also nullable. class
es are reference types,struct
s are value types.- C# 9 introduces
record
s, which are intended to be immutable, e.g. for data to pass around between services. - C# 10 introduces
record struct
s, which have the behaviors of value types as well as records.record
s can be written asrecord class
, to differentiate them fromrecord struct
s (even though the latter were introduced later).
- Value types can implement interfaces, but not inherit from a base class.
Defining constructors
- In Visual Studio,
ctor
is a keyboard shortcut to scaffold a constructor (stub). - The constructor method has the same name as the class.
- A constructor can invoke the constructor of its base class like this:
public ClassA() : base("param1") { }
- Since C# 6, you can prefix a string with a
$
sign to have embedded variables (within{}
) interpolated. - In a method signature, default values can be provided for arguments, making them optional.
Object initialization
- Instead of using a constructor to initialize (create) an object, we can use object initialization to set any property we want. Notice the curly braces instead of the parentheses:
Employee e = new Employee{ FirstName = "Claus", LastName = "Conrad"; };
- Object initialization (as shown above) is shorthand for calling the default constructor (without arguments) and then setting the properties.
- It can also be combined with another constructor, e.g.
Employee e = new Employee("Claus"){ LastName = "Conrad"; };
- “Roslyn” is the name of a specific C# compiler that is itself implemented in C# (similar to how PyPy is a Python interpreter written in Python).
- Any constructor for a
struct
needs to set a value for all properties (since astruct
is a value type).
Initialize only properties
- A property declared with
init
instead ofset
can only be set by a constructor or using object initialization:public byte CustomerLevel { get; init; }
- This is often used on
record
types to make their values immutable. - The access of
get
andset
can be controlled, e.g.public int YearsOld { get; private set; }
Cloning and copying objects
- A reference type (such as an instance of a
class
, a.k.a. an object) can have multiple variables pointing at it.- By default, when a (reference type) variable is passed to a method and the method assigns something else to the variable, that change does not persist after the method returns.
- This behavior can be changed by prefixing the variable with
ref
- both in the method definition (signature) and when calling it (argument list). In this case, if the method changes what “object” the (reference type) variable points at, the original variable is modified, and so the change persists after the method returns.
- When a new variable is assigned a
struct
(i.e. a value type), then the value is copied, and the two variables (while they initially have the same value) can be modified independently from here on.- The same applies when a
struct
is passed to a method - a copy local to the method is created, and changes to it do not persist after the method returns. - This behavior can be changed by prefixing the variable with
ref
- both in the method definition (signature) and when calling it (argument list). In this case, if the method changes the “struct” (the value type), the original value is modified, and so the change persists after the method returns.
- The same applies when a
- The
with
keyword can be used to copy arecord
with modifications, e.g.public record Customer { /* ... */ } Customer c = new Customer{ FirstName = "Claus", LastName = "Conrad" }; Customer c2 = c with { Lastname = "Clausen" };
Equality comparisons
- A
record
can be defined using two different syntaxes:- Similar to a
class
:public record RClassLike { public int Id { get; set; } }
- Shorthand syntax:
public record RShorthand(int Id);
- In the shorthand example, this defines the
record
, its constructor and its single property at the same time. TheId
can only be set using this constructor (or using this constructor and an object initializer, but that does not make sense here) and is read-only afterwards (i.e. this syntax is similar to using theinit
keyword).
- Similar to a
- By default, when comparing for equality,
- for
struct
s, the equality operator (==
) is not defined (but the developer can implement it); - for
class
instances, equality means whether they point to the same object; - for
record
s, the framework checks whether all properties have the same value.
- for
- When overriding/implementing the
==
/!=
operators, one should also override/implement theEquals()
method.