C# Particularities
Here we will discuss some particularities of programming in C# compared to other web frameworks; more extensive information can be found in this course. One important feature in C# is extension methods. These are compiler tricks that add new methods to existing classes and can be called as if they were non-static methods of these extended classes. Extension methods are useful for extending functionality for existing code without modifying it.
Below you have examples of extension methods for the WebApplicationBuilder class; practically, the .UseLogger() method is added to WebApplicationBuilder to add a more complex logger to this builder. The keyword "this" in the first parameter of this static method in the static class specifies to the compiler to treat it as if the first parameter is "this" and the method is a non-static method of the class.
public static class WebApplicationBuilderExtensions
{
public static WebApplicationBuilder UseLogger(this WebApplicationBuilder builder)
{
builder.Host.UseSerilog((_, logger) =>
{
logger
.MinimumLevel.Is(LogEventLevel.Information)
.MinimumLevel.Override("Microsoft", LogEventLevel.Warning)
.MinimumLevel.Override("System", LogEventLevel.Warning)
.MinimumLevel.Override("Microsoft.Hosting.Lifetime", LogEventLevel.Information)
.Enrich.FromLogContext()
.Enrich.WithMachineName()
.Enrich.WithProcessId()
.Enrich.WithProcessName()
.Enrich.WithThreadId()
.WriteTo.Console();
});
return builder;
}
}
A particular case for the utility of extension methods is LINQ operations on collections. In the section on database interaction, you saw how multiple functional expressions can be chained to extract information from the database. Those methods are the same for all database context implementations; they are extension methods for "this" IEnumerable. They just call the public methods of this interface; the same interface is implemented by classic collections in the standard language library. This means the same methods can also be used for processing lists, for example, and benefit the programmer by using a high level of abstraction for different contexts such as collections and databases.
Another particularity compared to languages like Java is that in C#, in addition to methods and fields, classes can have properties, which are fields with getters and setters. It is preferable to use properties instead of fields if they need to be public because they can also abstract values that are calculated on the spot without explicitly calling a method.
One last particularity that makes C# similar to languages like Kotlin is its support for asynchronous programming. If you follow the methods in the lab code, you will notice that most of them return a Task and have the "async" keyword. These methods are taken by the application's execution threads and executed asynchronously. It is not known exactly when they are executed; they are executed when scheduled by the framework to optimize their execution. Multiple tasks can be executed on the same execution thread, and within an "async" function, you can "await" another task to suspend the execution of the current task and wait for the execution of the awaited task.