In this article I will document about some of the nice features C# has to offer. This include reason(s) for choosing C# in terms of the amount of time needed to bring that app or technology to the market. This could only be a subset of all the features available or known yet.
1. Entity Framework model - Helps in building apps with a decent list of SQL database support like SQLite, MSSQL, Oracle and all. All these are supported by simply inheriting the DBContext to your class and having declared `DBSet<Type>` in that class. You may install the entity framework CLI tool for migrations like below.
// Installs the CLI ef tool
dotnet tool install --global dotnet-ef
// Installs the nuget package for EF operations in your project
dotnet add package Microsoft.EntityFrameworkCore.Design
// Creates new migration for the model just created like Type
dotnet ef migrations add InitialCreate
// Updates the model to the database
dotnet ef database update
Benefits are no prior database knowledge or tools are required to create and manage the database and tables and all. The class `Type` easily translates to the table (schema) in the database. Having said that a good database architect knowledge helps in designing and updating the database with primary and foreign keys and all. Other than that it is a nice practice to commit the migrations to the source control.
2. OData support - If you are building a MVC app with API's returning a bigger set of data like a list of objects. This new* library helps to pass custom query to filter and sort the returned data by just adding an annotation to the specific controller like `[EnableQuery]`. This in turn reduces the extra lines of code needed to be written in the controllers to perform the same.
3. Razor pages support - If you are building a web app then Razor pages of the ASP .Net can help. Razor is the templating pages from MS. You can have both the C# code and the HTML in them. This helps in building web pages for the front end and accessing or calculating the data in the C# code. This can include independent services created and running using the Dependency injection adhering to the D (Dependency Inversion) in the SOLID principles of the OOP design pattern.
Pages end with .razor extension was initially created as a component. Higher components can call the lower (or inner) components and data can be passed to them using the `[Parameter]` or
`[CascadingParameter]`
as annotations to the individual properties. Blazor uses razor pages and .cshtml pages can include .razor pages declared like <ComponentName /> html tags
4. Multi threading or parallel programming -
a. Libraries like `System.Threading.Monitor` helps to lock thread execution to a single thread. Parameters include passing `timeout`(s), `bool ref flag` to check if thread is running ( in critical section ) or not.
b. `Sempahore(minThreadCount = 0, maxThreadCount = 3)` contructor to support OS level named semaphores which can be utilized by other programs in the OS as well using the same name. `SemaphoreSlim` to make use of the program level semaphores to control a small number of threads to run in parallel.
c. Data structures like `Interlocked.Increment(.... int ....)` or `Decrement()` help in parallel threads increasing or decreasing a number. `ConcurrentDictionary`,
`ConcurrentQueue`,
`ConcurrentBag` types can be used for thread safe data type operations.
d. A simple `lock(obj) { ... }` loop can be used for running or making thread safe single thread operation(s).
e. Parallel.Invoke(action1, action2, ..... ) is used to run as many actions as needed in parallel.
5. LINQ - Language Integrated Query -
Can be used on almost any `Enumerable` type which helps in mainly filtering and ordering data using .Select( ..... ) and .Where( ...... ) clauses in the enumerable types.
Benefits include a ton of time saved writing the `foreach` or any loops with conditions to iterate and all with almost a single line in many cases*.
6. Actions or Funcs or Delegates
Actions<T> are delegates but have no return value to them, unlike Funcs<T, U> for which the last parameter of type U can be the return type of the method.
7. Generics
Used in classes or methods are types which can be passed as different types and a subset of types can be specified. These help in class or method overriding meaning saving duplicate methods for each different methods.
8. Dependency Injection
In order to achieve the inversion of control support in the SOLID principles, C# offers injecting the Services or Types as dependencies during load time in an ASP .Net app like `
builder.Services.AddScoped<IService, Service>();` . The type Service can be Transient,
Scoped
or Singleton depending on the lifetime needed.
Transient is new instance every time,
Scoped
is one instance for the lifetime of the app and the Singleton is the same instance forever like a `static` type.
9. HttpFactory for clients
Often there can be issues when trying to make http calls in terms of the resources utilized in the OS. The HttpFactory or the HttpClient typed cient can be injected to a particular service to let the DI handle such resources and try and avoid the socke exhaustion issues, HttpClientFactory helps to create http named clients which can be used in the app anywhere with the same settings. Or a factory for each different client can be created during launch and used within the app interchangeably.
10. Grpc support
Google's newer RPC using the http protocol internally is gaining ground in terms of the security offered during transportation and the communications. C# has OOB support for this, be it starting a complete client server app, enabling and making gRPC calls from the CLI and all.
11. Mock or Stub testing
There is a popular C# nuget package called `Moq` which help in creating stub or mock objects for interfaces with method definitions. This can be initiated to -Arrange the test data as desired to be returned by each or all the methods and -Assert ed at last to test the parts or services not covered by the stub or mock. This is mainly used when calling such dependencies (as mocks) include network or app being up and running. These are mainly used in unit test(s) and provide a reasonable coverage to the programs in that repository when deploying in the CI/ CD pipelines.
Apart from helping write valuable test(s), this helps in building TDD apps and promotes programmers write unit tests first and then the classes after the interfaces. This helps in updating the OOP programs following say L (Linquist substitution) and O (Extend but not modify used classes) in SOLID priciples.
12. Dotnet CLI
One important aspect of the C# development worth mentioning is the CLI support. When installed on popular OS, C# can be easily compiled using `dotnet build` and run using `dotnet run Debug`, be it powershell or bash and all.
13. Configuration management
App configuration(s) are easily stored in `appsettings.json` for production and
`appsettings.Development.json` for development. Indidividual json files with setting can be loaded on services load and used within the app as `IConfiguration _configuration` type which can load a setting like { "AppName": "AppOne" } and retrieved easily as
`var appName = _configuration[
"AppName"
];` within the app.
14. Parallel For loop
`Paraller.For` or `
Paraller.ForEach
` loop is new feature where the loop runs in parallel and thread safety should be kept in mind when writing such programs.
15. Editor
`Visual Studio` is supposed to be the go to editor as it is from MS as well. Having said that `VSCode the MS version` is no less powerful compared to its multi OS support and some nice extensions such as `C#`, `C# Extensions`, `Roslynator`, `GitHub Copilot`, `.Net Extension Pack`, `.Net Core Test Explorer` and `Solarized` as well.