How to implement a C# concept exercise
January 28, 2021 · View on GitHub
This document describes how to implement a concept exercise for the C# track.
Please please please read the docs before starting. Posting PRs without reading these docs will be a lot more frustrating for you during the review cycle, and exhaust Exercism's maintainers' time. So, before diving into the implementation, please read the following documents:
Please also watch the following video:
As this document is generic, the following placeholders are used:
<SLUG>: the slug of the exercise in kebab-case (e.g.calculator-conundrum).<NAME>: the name of the exercise in PascalCase (e.g.CalculatorConundrum).<CONCEPT_SLUG>: the slug of one of the exercise's concepts in kebab-case (e.g.anonymous-methods).
Before implementing the exercise, please make sure you have a good understanding of what the exercise should be teaching (and what not). This information can be found in the exercise's GitHub issue. Having done this, please read the C# concept exercises introduction.
To implement a concept exercise, the following files must be added:
languages
└── csharp
├── concepts
| └── <CONCEPT_SLUG>
| ├── about.md
| └── links.json
└── exercises
└── concept
└── <SLUG>
├── .docs
| ├── instructions.md
| ├── introduction.md
| ├── hints.md
| └── source.md (required if there are third-party sources)
├── .meta
| |── config.json
| |── design.md
| └── Exemplar.cs
├── <NAME>.cs
├── <NAME>.csproj
└── <NAME>Tests.cs
Step 1: Add code files
The code files are track-specific and should be designed to help the student learn the exercise's concepts. The following C# code files must be added (not necessarily in this order):
Add <NAME>.cs file
Purpose: Provide a stub implementation.
- The stub implementation's code should compile. The only exception is for exercises that introduce syntax we want a student to define themselves, like how to define a class or property. In this case, insert a descriptive TODO comment instead of providing stub code (see this example).
- Stub methods should throw a
NotImplementedExceptionwhich message contains the method to implement, see this instance method example. The message is subtly different for static stub methods, see this static method example.
For more information, please read this in-depth description, watch this video and check this example stub file.
Add <NAME>Tests.cs file
Purpose: The test suite to verify a solution's correctness.
- xUnit is used as the test framework.
- Only use
Facttests; don't useTheorytests. - All but the first test should be skipped by default (check this example).
- Test methods must be named using
snake_case, with the first character uppercased (check this example). - Test methods must have a single assertion.
For more information, please read this in-depth description, watch this video and check this example tests file.
Add <NAME>.csproj file
Purpose: The project file required to build the project and run the tests.
For more information, check this example project file.
Add .meta/Exemplar.cs file
Purpose: The idiomatic example implementation that passes all the tests.
For more information, please read this in-depth description, watch this video and check this example file.
Step 2: Add documentation files
How to create the files common to all tracks is described in the how to implement a concept exercise document.
Step 3: Update list of implemented exercises
- Add the exercise to the list of implemented exercises.
Step 4: format code
All C# code should be formatted using the dotnet format tool. There are two ways to format your C# code:
1. Using a GitHub comment
If you add a comment to a GitHub PR that contains the text /dotnet-format, a GitHub workflow will format all C# documents in the PR using dotnet format. Any formatting changes made by dotnet format will automatically be committed to the PR's branch. This also works for forks that have enabled maintainers to edit the fork's PR (which is the default).
2. Using a script
Open a command prompt in the language/csharp directory and then run:
./format.ps1 <SLUG>, where<SLUG>is the exercise's directory name.
Step 5: Add analyzer (optional)
Some exercises could benefit from having an exercise-specific analyzer. If so, specify what analysis rules should be applied to this exercise and why.
Skip this step if you're not sure what to do.
Step 6: Add representation (optional)
Some exercises could benefit from having an custom representation as generated by the C# representer. If so, specify what changes to the representation should be applied and why.
Skip this step if you're not sure what to do.
Inspiration
When implementing an exercise, it can be very useful to look at already implemented C# exercises like the log-levels, datetimes or floating-point numbers exercises. You can also check the exercise's general concepts documents to see if other languages have already implemented an exercise for that concept.
Help
If you have any questions regarding implementing the exercise, please post them as comments in the exercise's GitHub issue.