01.1 - Course Intro & Tooling
Recap
This is the first lecture of the course, so there is nothing to recap yet. Week 1 is about getting the tools right: by the end of week you should have a compiling solution in your own course git repository and know your way around the dotnet CLI and Rider.
By the end of this lecture you should be able to:
- Explain how the course runs: flipped classroom, three defences, one repository per student, code freeze.
- Tell the .NET runtime, the BCL and the SDK apart, and place .NET Framework, modern .NET, Mono and .NET Standard on a timeline (learning outcome L01).
- Create the course solution from the command line with
dotnet new,dotnet sln add,dotnet add reference,dotnet build,dotnet runanddotnet test. - Set up
global.json,Directory.Build.props(nullable on, warnings as errors) and.gitignorebefore the first commit. - Follow the daily git workflow, including the
d1/d2/d3fallback tags.
Lecture demos: csharp-2026-fall
Course format in 10 lines
- Flipped classroom. Watch this week's videos (~90 min) before Friday. Friday 09:00-12:00 in ICO-221 is an optional clinic: demos, questions, help with your code. Nothing new is lectured there.
- One evolving project. Everybody builds a two-player board game — console app first, web app later — split into class libraries so the console UI and the web UI share the same engine and storage.
- Your game is fixed by your student code. Last digit of the numeric part, integer-divided by 2: 0 → Connect Four, 1 → Tic-Tac-Two, 2 → Reversi/Othello, 3 → Gomoku, 4 → Nine Men's Morris. No proposals, no swapping.
- One repository per student. The git server, repository naming and setup are defined in Git usage. README with your name, student code, uni-id and game.
- Six assignments. A1 (menu library) is standalone; A2-A6 are cumulative in the same solution. A1 starts today and is due in Week 3.
- Three defences. D1 in weeks 6-7 (A1+A2+A3, 30 p), D2 in weeks 11-12 (A4+A5, 30 p), D3 in weeks 16-17 (A6 + demo, 40 p). Each period runs on two consecutive Fridays; book a slot on either.
- Code freeze is Thursday 23:59:59 before the first Friday of each period (08.10, 12.11, 17.12). The frozen commit is graded, whichever Friday you defend on.
- Passing. Every defence needs more than 50% of its points. One retake in total, capped at 75% of the original points, only on the retake Friday (weeks 8, 13, 18).
- Grades. 120 points max (100 base + 20 bonus): 5 = 90+, 4 = 80-89, 3 = 70-79, 2 = 60-69, 1 = 50-59.
- AI is encouraged. Keep a short AI usage log in the repository. At the defence you explain every line without AI help — if you cannot, it is not your code.
The syllabus is the contract; this list is the summary. Read the extended syllabus once, properly, this week.
The .NET landscape
Runtime, BCL, SDK
- Runtime (CoreCLR) loads the intermediate language (IL) your build produced, JIT-compiles it to machine code, runs the garbage collector and enforces type safety. End users need only this.
- BCL (Base Class Library) is the standard library: everything under
System.*. It ships together with the runtime. - SDK = runtime + BCL + compiler + MSBuild + NuGet + the
dotnetCLI + templates. You install this. Rider uses the SDK under the hood; it does not bring its own compiler.
dotnet --version # 10.0.xxx — the SDK version
dotnet --info # every SDK and runtime installed on this machine
.NET Framework vs modern .NET vs Mono / .NET Standard (L01)
| .NET Framework | Modern .NET | Mono | .NET Standard | |
|---|---|---|---|---|
| What | The original 2002 Windows-only platform | Cross-platform successor (Core 1.0 → .NET 5 → .NET 10) | Independent open-source implementation (Xamarin, Unity, early MAUI) | Not a runtime: an API contract a library promises to use |
| Status | 4.8.1 is the last version; security fixes only | Actively developed, one release every November | Absorbed into the .NET code base; lives on inside Unity and the browser/WASM runtime | Frozen at 2.1; only for libraries that must still run on .NET Framework |
| For you | Legacy code you may meet at work | Everything in this course targets net10.0 | Know that it exists | Know what it is; never target it for new code |
LTS vs STS
- Even versions (6, 8, 10) are Long Term Support: 3 years. .NET 10 shipped in November 2025 and is supported until November 2028.
- Odd versions (7, 9, 11) are Standard Term Support: 24 months.
- The course uses .NET 10 LTS and C# 14. Every project has
net10.0as itsTargetFramework; C# 14 is the default language version for that target, so no extra setting is needed.
The dotnet CLI: building the course solution
Rider can do all of this through dialogs, but the CLI is faster, scriptable and works on a machine with no IDE — and at the defence the first step is a fresh clone followed by dotnet build and dotnet test in a terminal.
mkdir icd0008 && cd icd0008
dotnet new sln -n icd0008 # solution file (add --format slnx for the XML format)
dotnet new classlib -n MenuSystem # class library: no Main, produces a DLL
dotnet new console -n ConsoleUI # executable
dotnet new xunit -n Tests # xUnit test project
dotnet sln add MenuSystem/MenuSystem.csproj ConsoleUI/ConsoleUI.csproj Tests/Tests.csproj
dotnet add ConsoleUI/ConsoleUI.csproj reference MenuSystem/MenuSystem.csproj
dotnet add Tests/Tests.csproj reference MenuSystem/MenuSystem.csproj
dotnet build # compiles every project in the solution
dotnet run --project ConsoleUI # builds if needed, then runs
dotnet test # discovers and runs the xUnit tests
dotnet new gitignore # .gitignore tuned for .NET (bin/, obj/, .idea/ ...)
The result:
icd0008/
├── icd0008.sln
├── .gitignore
├── MenuSystem/
│ ├── MenuSystem.csproj
│ └── Class1.cs ← delete, add MenuItem.cs / Menu.cs
├── ConsoleUI/
│ ├── ConsoleUI.csproj
│ └── Program.cs
└── Tests/
├── Tests.csproj
└── UnitTest1.cs
The solution grows during the semester. Dependencies always point inwards, from UI towards logic; a library never references a UI project.
A project file is plain XML. After the commands above ConsoleUI/ConsoleUI.csproj looks like this:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\MenuSystem\MenuSystem.csproj" />
</ItemGroup>
</Project>
Everything in the project folder is compiled automatically — there is no list of source files. Other commands you will use weekly:
dotnet new list # all templates (console, classlib, xunit, web, razor, gitignore ...)
dotnet clean # remove bin/ and obj/
dotnet build -c Release # release configuration
dotnet watch run --project ConsoleUI # rebuild and rerun on every file save
dotnet test --filter "FullyQualifiedName~MenuTests"
dotnet run needs to know which project: either cd into the project folder or pass --project. Running it at the solution root without --project fails with "Couldn't find a project to run".
JetBrains Rider tour
Rider is free for non-commercial use; a student licence via your university e-mail unlocks everything else. Open the solution file, not the folder.
- Solution Explorer (left): projects, files, the Dependencies node with project and package references. Right-click a project → Add → Reference... is the GUI version of
dotnet add reference. Enable Show All Files to seebin/andobj/. - Run configurations (top right): one per executable project, created automatically. Open the configuration and tick Emulate terminal in output console — without it
Console.ReadKey, colours andConsole.Clearmisbehave in the run tool window. Or run from a real terminal. - Debugger: click the gutter to set a breakpoint, run with the bug icon. Step over / step into / step out / resume are F8 / F7 / Shift+F8 / F9 on the IntelliJ keymap (Rider's default on macOS) and F10 / F11 / Shift+F11 / F5 on the Visual Studio keymap (default on Windows). Hover a variable to see its value; use Watches and Evaluate Expression. Right-click a breakpoint for a condition — priceless when a bug appears on move 37 only.
- Terminal (bottom): a real shell inside the IDE; run the
dotnetandgitcommands there. - Database tool (right): from Week 6 you open SQLite files here, browse tables, run SQL and inspect what EF Core generated.
- NuGet window (bottom): search, install and update packages per project — equivalent to
dotnet add package. - Daily actions, whatever the keymap: Alt+Enter (quick fix / refactor), Shift+Shift (search everywhere), Go to Type, Reformat Code, Rename (renames every usage in the solution). Look them up once in Help → Keyboard Shortcuts PDF for your keymap.
Turn on Solution-Wide Analysis (status bar, bottom right). Rider then shows every error in the whole solution, not only in open files — exactly what dotnet build will report.
NuGet basics
NuGet is the .NET package manager; nuget.org is the public feed. A package is a zip with compiled DLLs per target framework plus metadata.
dotnet add ConsoleUI/ConsoleUI.csproj package Microsoft.EntityFrameworkCore.Sqlite
dotnet add ConsoleUI/ConsoleUI.csproj package Microsoft.EntityFrameworkCore.Sqlite --version 10.0.0
dotnet list package --outdated
dotnet restore # normally implicit in build/run/test
The command adds a PackageReference line to the csproj — that line is the source of truth, and it is what you commit. Packages themselves download into ~/.nuget/packages and are resolved into obj/project.assets.json; neither goes into git. Package references are transitive: ConsoleUI referencing DAL.EF automatically gets EF Core.
A1 is your menu library. Third-party console UI packages (Spectre.Console, Terminal.Gui and friends) are off limits for the menu itself. Anything you did not write, you cannot defend.
global.json
global.json at the solution root pins the SDK version so that you, the TAs and the CI all build with the same toolchain.
{
"sdk": {
"version": "10.0.100",
"rollForward": "latestFeature"
}
}
latestFeature means: any 10.0.x SDK is fine, but never silently jump to .NET 11. Create it by hand or with dotnet new globaljson --sdk-version 10.0.100 --roll-forward latestFeature. Check with dotnet --version from inside the folder.
Directory.Build.props: the course rule
MSBuild automatically imports a file named Directory.Build.props from the solution root into every project below it. One file switches on the same settings for all seven projects, and no project can forget them.
<Project>
<PropertyGroup>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>
</Project>
Nullable reference types on and warnings as errors — in this course and in Web Applications with C# next spring. A project without this file, or with the rule disabled through WarningsNotAsErrors, NoWarn or #pragma warning disable, is not accepted at the defence.
What this means in practice:
string name;as a property or field is now an error (CS8618: non-nullable member must contain a non-null value). Initialise it:= "";,= new();,= default!;, mark itrequired, or set it in the constructor. Week 2 covers the patterns.string? input = Console.ReadLine();is fine — the?says null is allowed, and the compiler then forces you to check before using it.- An unused variable, an unreachable
case, a missingswitcharm: all compile errors. Fix them, do not hide them.
Create the file with dotnet new buildprops (then edit) or by hand. Put it next to the .sln.
Git workflow
Create your course repository exactly as described in Git usage — that page defines the git server, the repository name and the project settings. Then clone it and put the solution and a README (name, student code, uni-id, assigned game) in it:
git clone <repository-url> # the HTTPS URL shown on your repository page
cd <repository-name>
# create the solution here (dotnet new sln ... as above)
dotnet new gitignore
git status # bin/ and obj/ must NOT be listed
git add .
git commit -m "Solution skeleton: MenuSystem, ConsoleUI, Tests, build props"
git push
The daily rhythm:
git pull # if you work on more than one machine
# ... code, dotnet build, dotnet test ...
git add .
git commit -m "MenuItem: validate shortcut is a single character"
git push # every time you stop working
- Commit small and often. One commit per feature or fix, with a message that says what changed. Ten commits a week is normal; one commit the night before code freeze is a red flag — and if your laptop dies, so does your work.
- Tag before every defence. When the code compiles and runs on Thursday, tag it. If a later commit is broken, you can ask to fall back to the tag.
git tag -a d1 -m "D1 code freeze"
git push origin d1
- Never commit:
bin/,obj/,.idea/(Rider settings),*.db/*.db-journal(SQLite files),.vs/,.DS_Store, secrets.dotnet new gitignorecovers the first three; add*.db*yourself when you reach Week 6.
If something slipped in:
git rm -r --cached ConsoleUI/bin ConsoleUI/obj
git commit -m "Remove build output from git"
No git push --force to main, no history rewriting after code freeze. The TAs grade the commit that is on the git server on Thursday 23:59:59 — nothing else exists.
The check that tells you whether you are ready: clone your own repository into a temporary folder, run dotnet build and dotnet test. Both green means you have committed everything that matters and nothing that does not.
Self preparation QA
- What is the difference between the .NET runtime and the .NET SDK? — The runtime executes compiled apps (CoreCLR + BCL); the SDK adds the compiler, MSBuild, NuGet and the
dotnetCLI needed to build them. - Why is .NET Standard irrelevant for new code in this course? — It is only an API contract for libraries that must also run on .NET Framework; all our projects target
net10.0directly. - What does LTS mean for .NET 10? — Three years of support (until November 2028); STS releases get 24 months.
- Which command lets
ConsoleUIuse classes fromMenuSystem? —dotnet add ConsoleUI/ConsoleUI.csproj reference MenuSystem/MenuSystem.csproj; it becomes aProjectReferencein the csproj. - What does
Directory.Build.propsdo and where does it go? — MSBuild imports it into every project below it, so one file at the solution root switches on nullable, implicit usings and warnings-as-errors for the whole solution. - What do
bin/,obj/and.idea/have in common? — All are generated or machine-specific; none belongs in git, anddotnet new gitignoreexcludes them. - What is the code freeze and how does a
d1tag help? — Thursday 23:59:59 before the first defence Friday; a tag marks a known-good commit you can fall back to if the last commit does not compile. - What is
global.jsonfor? — It pins the SDK version (with a roll-forward policy) so everyone building the project uses the same toolchain.