Seven Peaks Insights

Introducing the new C#

C# basics & developing with Rabbit MQ



C# basics – C# Version History

To start with the C# basics, let’s recap to the old version of C# 1.0, since it released its first version in January 2002 (which was just a basic version) and to now they’re continuing the version 2.0 three years later in November 2005. This is a huge update, it’s like a generic and honorable tie with Rabbit MQ and other useful features that we have now – as we’re still using the C# basic 3.0 two years later.

Three years later, we have C# 4.0 introduced generics co- and contravariance which is another useful feature. And then a C# five introduced two years later with Async features that we are using in the framework of 4.5. Continue on to July 2015, we have version 6.0, released with the first version of .NET Core.

It’s released with a bunch of useful features like String Interpolation which seems to be simple but a very useful feature. And we have two minor versions of the C# 7.0. The latest one compared to C# version 8.0 which came with .NET Core 3.0 and current Visual Studio 2019 that we are mostly using this version in our development.


9 Features tied to the C# Basics

The latest version of C# is version nine and is currently in the preview version. This version of C# aims to shorten code and create immutable objects with OOP (object-oriented programming). You can start learning the C# with less boilerplate code since it gives a better understanding of what is going on and it is also easy to stock.

Target typing helps to shorten the codes when you create a new instance of your object.

For Init-only features, this version of C# will try to be more immutable data. So it can represent the data without modifying anything. It is quite useful if you want to keep the history and the context, the immutable is the answer for you. The other feature is records which are immutable to your whole object, not just only the features or the property.

Top Level Statements

In previous version of C#, writing a simple programming language requires huge amounts of boilerplate code. In the new version, C# 9.0, they just reduce the code and it works just the same. As for beginners to start running the C# basics, you can just choose to write the main program at the top level. You can just leave out the type if there’s a clear type.

Try this code:

using System;
Console.WriteLine(“Hello World!”)


New expressions:

With the new expressions in C# 9.0, you don’t really need to specify the type after the new keyword.

Try this code:

//C# 9.0 Person person = new(“Prayuth”, “Sudjai”);
var people = new Person[]
new (),
new (“Donald”, “Duck”),
new () { FirstName = “Taylor”, LastName = “Swift” },

Conditional expressions

Expressions don’t share the same type between branches. Now C# 9.0 will allow shared target type between branches.

Try this code:

public class Person {}
public class PrimeMinister : person {}
public class President : person {}
Null-Coalescing operator (??) works with common base type
Person person = president ?? primeMinister;
Ternary operator (?:) works with nullable value type
int? result = notnull ? 0 : null;

Covariant returns

Previously, the signature of the method that you want to return, it has to be the same type as the base class. The advantage is you can express that the method has a more exact return type than the one in the base type.

Try this code:

public virtual Person GetPerson()
return new Person();
public override President GetPerson()
// no need casting!
return new President();

Init-only Features

It gives the client the type of readable format to create an object. You can set the value only once when it’s initializing in the constructor.

Try this code:

public class Person
public string FirstName { get; init; }
public string LastName { get; init; }
public Person(string firstName = null,
string lastName = null) =>
(FirstName, LastName) = (firstName, lastName);


Records would be useful if you want to keep the data history such as sourcing and object value. Records can work with expressions, you can use a with-expression when you want to copy the object.

You can also give the new value, so the new object will get all the data from the old object plus the new value you assigned inside the object initializer which gives two different objects.

Try this code:

public record Person
public string FirstName { get; init; }
public string LastName { get; init; }
public record Person(string FirstName, string LastName)



How does this work behind the scene of the record?

Basically, you can use them with expressions when you want to clone the object. It is just working behind the scene by creating the prohibited constructor which you can copy field by field.

Try this code:

var newPerson = person with { LastName = “Alpha” };
protected Person(Person original) { /* copy all the fields */ } //

Value-based equality

Value-based equality is used to see if the same object is equal or not. And for the ReferenceEquals type this will be used to specify two object parameters when both parameters are non-null. But for the Equals, you can use without reference which will give you the true value of two different objects.

Try this code:

Object.Equals(object, object)
ReferenceEquals(person, newPerson) = false
Equals(person, newPerson) = true



Besides spending time rewriting code from scratch since you may face issues like technical debt, or the maintenance costs are too high. There is another option which is better for business: we separate the monolith application into smaller services.

How can they connect to each other and communicate more efficiently?

In order to glue services together in the decoupled fashion, here comes the reason why the messaging queue platform is created. So here’s the benefit, we can decouple applications into smaller services based on the business boundary.

By that, we can scalability the service if we have multiple services. Only some services are busy with processing so we can scale up or scale out for that particular service. Also, we can really gain a better UX because many of tasks can be processed asynchronously. From the client side, customers don’t have to wait until it’s done.

Why Rabbit MQ?

There are so many messaging platform providers such as Apache Kafka, Azure Service Bus, Google Cloud Pubsub, Rabbit MQ and more. We will give you a quick idea about Rabbit MQ as it is one of the most successful messaging services to be introduced.

As Asia service bus or Google pub sub, you will have to host it in Asia or in Google Cloud. So it’s going to be a bit difficult to migrate from one cloud provider to another. Rabbit MQ is a very mature platform and has been developing for a long time. There are a lot of client libraries in multiple languages so it supports most languages – not only for the C# basics, Java, and Python.


Advanced Message Queueing Provider (AMQP)

AMQP is a protocol that originally developed to be used for the financial industry to support AMQP 0-9-1.


Queue is where messages are stored. It has a publisher on one side and a consumer sitting on the other side waiting for the message and processing it.

Exchange and Binding

Exchange is responsible to decide what to do with messages. Basically exchange stands between publishers and the queue. Once the publisher sends a queue to exchange and exchange will decide which queue to be delivered by configuration which is called binding.

Exchange types

Fanout Exchange

A fanout exchanges copies and equally distributes messages to all queues that are bound to it regardless of what messages are.

Direct Exchange

For direct exchange, publishers need to specify the routing key in the message and we have to configure the routing key beforehand.

In this example, the Q1 will be listening to any messages whose binding key exactly matches orange and the Q2 will be listening to any messages which are about black and green.

Topic Exchange

Topic is the most popular exchange type similar to direct exchange which we are still utilizing routing keys as before. However, there are more features in topic type. We can use star and hash symbols as wildcards. Star can substitute exactly one word and hash can substitute zero or more words.

Header Exchange

A header exchange uses the message header attributes for routing. It distributes messages based on arguments which include headers and optional values.

Do you need help with your Back-end development?
Get in touch with us below to see how we can help you!
Get in Touch!