Løsning og projekt
En C# løsning (solution på engelsk – løsning på dansk er en lidt skidt oversættelse) består typisk af et eller flere projekter, og et enkelt projekt kan være en konsol-applikation (ligesom du oprettede i forrige afsnit), en web-applikation, en Windows-applikation, mobil-applikation og meget andet.
Information til undervisere
Vis kursisten indholdet i en .sln-fil og en .csproj fil. Skab eventuelt et simpelt eksempel med en løsning bestående af en konsol app og et klassebibliotek
En løsning er repræsenteret af en .sln-fil, og du kan finde en visuel repræsentation i Solution Explorer-vinduet. Der kan kun være én løsning ad gangen i VS/VSC, men du må gerne have flere udviklingsmiljøer åbne på samme tid.
Tip
Hvis du arbejder med VSC, er der ikke nødvendigvis en .sln-fil, der repræsenterer en løsning. Men den kan tilføjes med kommandoen ”dotnet new sln”.
Hvert projekt kan være opdelt i flere filer, som kompileren vil sørge for at kompilere sammen. Et projekt er repræsenteret af en .csproj-fil, og består typisk af en eller flere .cs-filer med kode samt eventuelle konfigurationsfiler. Der kan være mange projekter under hver løsning.
Et projekt kan have en filstruktur som følger:
Hvis du åbner .sln-filen eller csproj-filen i Notepad, vil du kunne se, at det er filer VS bruger til at holde styr på løsning og tilhørende projekter. Du vil sjældent tosse rundt i disse filer, men nu ved du, hvad de består af.
Du må gerne have mange cs-filer (kodefiler) i et projekt, og du kan organisere disse, som du ønsker i mapper. Typisk vil du have en .cs-fil til hver typedefinition, og dermed ende med mange filer, men du kan også vælge at have flere typer i samme fil – kompilereren er ligeglad.
Eksempel
For at se en konkret løsning med projekter kan du gøre følgende
- åbn en terminal og naviger til en temp-mappe
c:\temp
eksempelvis - opret en ny mappe
MinApp
og naviger til den - opret en konsol app med
dotnet new console -n MinApp.Console
- opret et klasse bibliotek med
dotnet new classlib -n MinApp.ClassLibrary
- opret en sln-fil med
dotnet new sln -n MinApp
- tilføj MinApp.Console til sln-fil med
dotnet sln .\MinApp.sln add .\MinApp.Console\MinApp.Console.csproj
- tilføj MinApp.ClassLibrary til sln-fil med
dotnet sln .\MinApp.sln add .\MinApp.ClassLibrary\MinApp.ClassLibrary.csproj
- prøv en
dir
for at se fil strukturen - åbn sln-filen for at se indholdet
- gå til MinApp.Console med
cd .\MinApp.Console\
- skab en reference fra MinApp.Console til MinApp.ClassLibrary med
dotnet add reference ..\MinApp.ClassLibrary\MinApp.ClassLibrary.csproj
- ret class1.cs i .\MinApp.ClassLibrary til
namespace MinApp.ClassLibrary;
public class Class1
{
public static string Test()
{
return "Test";
}
}
- ret program.cs i .\MinApp.Console til
- naviger til ./MinApp.Console og kør applikation med
dotnet run
- det skulle gerne resultere i
- som beviser at de to projekter er bundet sammen
Det er et kort eksempel på en løsning med to projekter. Det kan naturligvis også gøres i VS eller Rider, men mange gange er det faktisk nemmere og hurtigere at gøre fra en terminal.
Dine egne prompts til Github Copilot
Hvis du har adgang til Github Copilot (kræver et abonnement), kan du eventuelt hjælpe Copilot på vej ved at tilføje en fil med en prompt i roden af dit løsning.
Filen skal hedde copilot-instructions.md
, og ligge i mappen .github
. Husk - den skal ligge på samme niveau som din sln-fil (eller .csproj hvis du ikke har nogen sln-fil).
Du kan eksempelvis tilføje følgende indhold:
# Copilot Instructions for C# Course
These are the rules for code generation in C#:
## General Rules
- Code must always use **English** names for variables, methods, classes, etc.
- All comments must be written in **Danish**, using `// ...`.
- Every piece of code must be **thoroughly commented**, so that even readers with very little knowledge of C# can understand it.
- **All other communication (outside of code)** must be written in **Danish**.
## Structure
- Use **top-level statements** where possible.
- All **methods** should be placed at the top scope.
- All **types (classes, structs, etc.)** should be placed at the **bottom of the file**.
## Best Practices
- Always follow **known best practices** for C# (naming conventions, formatting, proper use of access modifiers, etc.).
- Do **not** use lambda expressions, delegates, or advanced language features.
- Keep the code **simple and clear**, since it is intended for beginners.
- Each example must be **self-contained** and runnable.
## Example
```csharp
// Dette program demonstrerer hvordan man kan beregne gennemsnittet af tal i en liste.
// Koden er skrevet så selv begyndere kan følge med.
// ------------------------------------------------------------
// Metoder placeres altid øverst i filen (inden typer)
// ------------------------------------------------------------
// Denne metode beregner gennemsnittet af en liste af heltal
static double CalculateAverage(List<int> values)
{
// Først tjekker vi om listen er tom
if (values.Count == 0)
{
// Hvis listen er tom, returnerer vi 0
return 0;
}
// Her summerer vi alle tal i listen
int sum = 0;
foreach (int v in values)
{
sum += v; // Vi lægger hvert tal til summen
}
// Til sidst deler vi summen med antallet af elementer for at få gennemsnittet
return (double)sum / values.Count;
}
// Her opretter vi en liste af heltal
List<int> numbers = new List<int> { 5, 10, 15, 20, 25 };
// Vi kalder en metode for at beregne gennemsnittet
double average = CalculateAverage(numbers);
// Vi skriver resultatet ud på skærmen
Console.WriteLine("Average is: " + average);
// ------------------------------------------------------------
// Typer placeres nederst i filen
// ------------------------------------------------------------
// Denne klasse er blot et eksempel og kan bruges til at udvide programmet senere
class ExampleHelper
{
public string Name { get; set; }
}
Dette er blot et eksempel. Du kan tilpasse instruktionerne, så de passer til dine behov.
Spørgsmål til AI
For at få mest muligt ud af AI-værktøjer som ChatGPT, er det vigtigt at stille klare og præcise spørgsmål (og skabe det rigtige kontekst - se her). Her er nogle spørgsmål til denne side:
Grundlæggende spørgsmål
- Hvad er forskellen på en solution (.sln) og et projekt (.csproj) i .NET?
- Hvorfor giver det mening at samle flere projekter i én løsning?
- Kan du forklare, hvordan Solution Explorer afspejler indholdet af .sln og .csproj?
- Hvad indeholder en typisk .csproj-fil, og hvad bruger værktøjerne den til?
- Hvornår giver det mening at have flere .cs-filer vs. flere typer i samme fil?
- Hvordan opretter jeg en løsning fra terminalen med
dotnet new sln
? - Hvordan tilføjer jeg et eksisterende projekt til en løsning med
dotnet sln add
? - Hvordan opretter jeg en konsolapp og et klassebibliotek fra terminalen?
- Hvordan opretter jeg en projektreference mellem to projekter (
dotnet add reference
) – og hvorfor?
Ekstra spørgsmål (til fordybelse)
- Hvad sker der, hvis .sln-filen mangler, men projekterne stadig findes – kan jeg bygge alligevel?
- Hvordan påvirker projektreferencer build-rækkefølge og afhængigheder?
- Hvilke alternativer findes til projektreferencer (fx pakke-referencer/NuGet), og hvornår bruger man hvad?
- Kan du vise et mini-eksempel på et klassebibliotek med en metode, der kaldes fra en konsolapp (og forklare namespaces)?
- Hvordan renamer man et projekt, så både mappe, .csproj-fil og namespaces hænger sammen?
- Hvad er forskellen på
dotnet run
i roden af løsningen vs. inde i et bestemt projekt? - Hvordan opretter man en test-projektmappe og kobler den på løsningen (fx
dotnet new xunit
+dotnet sln add
)? - Kan du vise, hvordan man læser og forstår de vigtigste elementer i en simpel .csproj (TargetFramework, ItemGroup, ProjectReference)?