Why You Should Always Use Curly Braces For Single Statement Blocks In C#

Some say it is a personal preference and it’s not a big deal. I’d say it is not a personal preference anymore to omit curly braces for single statement blocks … here is why:


A single statement is one line of code that usually sits below If, While or For commands.

if(string.IsNullOrEmpty(someStr))
   Console.WriteLine("someStr is empty. surprise!!!");

I used to think if it is a one liner, it’s cleaner to have it without curly braces. Even maybe put it in one nice and short line. After all, C# compiler allows it, who am I to disagree with that .. lol

I posted a while ago about how a newly joined developer affects how you should write code, we want to write the code in a way that it is easily readable by every team member in future and it also creates a structure that prevents future mistakes. Over my past years, I learnt that always using curly braces is one of those structures.

Curly braces makes the block less error-prone to future modifications by others.

What if someone decides to comment out that one-line:

if(string.IsNullOrEmpty(someStr))
   //Console.WriteLine("someStr is empty. surprise!!!");

What if someone adds a new line and forgets to surround the block with curly braces:

if(string.IsNullOrEmpty(someStr))
   Console.WriteLine("someStr is empty. surprise!!!");
   someStr = "Default string in case of being empty";

Curly braces make the code more organised in case of multiple if..else statements

if(varA > varB)
   Console.WriteLine("varA is bigger");
if(varA == varB)
{
   logger.Log("we got a match");
   CalculateFee(varA, varB);
}
if(varA < varB)
{
   var result = fetchItemsDatabase(varB);
   if(result is null)
      break;
   if(result.Length > 0)
     foreach(var item in result)
        Console.WriteLine(item);
   if(result.Length == 100)
   {
       logger.Log("Celebrating 100");
       Celebrate100();
   }
}

You see? It puts cognitive mental load in order to separate each block of code. God forbids, if indentation was not done right, it will get even worse and becomes a nightmare to maintain this code!

There is not much value for a single line block anymore

When this feature was introduced (perhaps in C/C++ compiler), I believe it was to save some space and shrink the code to make it more readable. Back then, functions and code blocks were quite lengthy and convoluted.

It is not the case anymore though. We now break down logics into small manageable pieces, the storage is cheap, compilers can handle millions of files in a project and most developers use multiple big screens to read the code. So there is no point in shrinking the code and saving some space by not using curly braces.

Takeaway

Use curly braces always 🙂

Be a Citizen Scientist and Help End Covid-19 Pandemic Faster

With everything going on because of Covid-19 pandemic, there has been damages to various aspects of the world. From recession in countries’ economies to people struggling with jobs and even worse people losing their loved ones. On the other hand, there has been a tremendous amount of great work from health-workers and doctors which we all appreciate every day.

It seems like the key to get out of this pandemic is to wait until Covid-19 vaccine is created. But why wait when we can help expedite it? … How?.. you ask … well, let me explain:

New form of donation, donate technology

We all are familiar with common forms of donations in the time of a crisis. Some donate money, some volunteer and donate their time, some donate (like doctors, nurses, engineers, etc.) their expertise and knowledge. All forms is appreciated and every bit helps.

In case of Coronavirus pandemic, there are many studies being done to understand the virus better, how it works and what its behaviours are and how it reacts to a certain chemical compound. Almost every university and lab has or had a study about Covid-19. Which is super-amazing 🙂 Most studies need gazillions of calculations or simulations to help them study the virus and its behaviours better. The problem is, it takes time and there isn’t a super-computer big enough to finish all these calculations in a proper time period.

But what if people voluntarily donate computing devices they have (PCs, Laptop, Mobiles, Gaming Consoles, Rigs, etc.), scientists can collect the power of them and use it? Well .. yes and That is what citizen scientist is.

A citizen scientist is someone who is willing to donate their excess computing resource to participate in a research

This way, scientists can combine and link the machines citizen scientists donate and run their calculations at scale.

But .. is it helpful?

The power in our hand

Let’s take a typical smart-phone as an example .. iPhone 6. It uses A8 chip which is a dual-core 1.4Ghz cpu. Now let’s compare it with the computing power used for two of the human achievements throughout the history:

  • In 1997, IBM deep blue managed to beat Kasparov the big-master of chess. An iPhone 6 is 1000 times faster and more powerful than that.
  • In 1969, Apollo 11 used a specific computer to help it navigate. An iPhone 6 is 32000 times faster and more powerful than Apollo guidance computer (AGC) which worked at 0.043MHz and 64Kbyte of memory. and it landed us on moon!

How to start

There are many distributed computing projects running across the world. Generally each project needs you to install an application on your PC, laptop, gaming device or phone. Then it can be configured on how much power it is allowed to use and when is the time for it to run. Folding@Home, Dreamlab, BOINC, IBM OpenPandemic, Charity Engine, PI Cloud and MyShake are just some of the different projects I found with a simple google search.

Dreamlab is an app that uses the power of your phone while you are sleeping. It is available for iOS as well as Android. It is focusing on different cancer studies as well as a special Covid-19 study from Imperial College London. You can choose which study you would like to participate in. You can also choose how much data you allow the app to use. With phones being almost as powerful as computers these days, a virtual super-computer like that can get a great amount of computing power while phones are being charged at nights.

On the other hand, Folding@Home (FAH) is a distributed computing project started in 2000. It studies folding and the movements of proteins in human bodies. It uses your unused computing power and make it to use to study when proteins misfold. It has helped with the study of cancers, infectious diseases and neurological diseases. On March 2020, the contribution from people got them to 1.5 exaFLOPS and even made them one of the first exa-scale super-computers! It is now focusing on Covid-19 moonshot project.

What do you think? Have you participated in any of these projects before?

PS: I am NOT affiliated with any of the projects above, I wrote this simply because I find this idea interesting and worth talking about.

What Is git and Why It Is Used For Software Development?

When a software is being worked on by a team of engineers, to increase productivity and decrease dependency, they usually work on different features. That means each developer work on a feature/story and will add/change various files. This can sometimes causes conflicts since multiple developers may need to change the same file. A change conflict is dangerous. It can introduce bugs, break the solution and make it impossible for other developers to continue their changes (dependency), or even worse it may cause you loosing some of your precious code and logic.

When there are multiple objects racing for the same resource, a common solution in software engineering is to put that resource in the control of a management system and let that system handle the requests. This is the concept behind a code repository.

A code repository is a central system that stores the source code in and accepts/rejects change requests from developers.

  • It can accept or reject changes from developers
  • It can identify conflicting change requests and notify people
  • It can accept code changes in a pre-defined format and therefore make it easier to enforce code quality checks
  • It can enforce a review before accepting a change
  • Since it knows about all the changes, it can give you a detailed history of all changes (who has done what)
  • It can even have features to built, test and deploy the software

Git (pronounced as geet (/ɡɪt/)) is a source code management system. It is widely used by small or large teams to handle changes. Before we dive more, you should know that git is different than github. Although they both have been built by the same person and team, git is a software and github is a website.

There are different systems out there. They’re usually called Source Control Management (SCM) or Version Control System (VCS) and each has their own way of working. Git has a simple model that I call it branch-and-merge. Every repository is created with a main branch which is called “master”. A developer creates a branch off master and work on his branch. Each branch is a full copy of the “master” branch. This means you have all the files in the master. In your branch you can add new files, modify existing files or delete files. Once the developer is finished, he merges his branch back to master. This means, all of the changes he made will be transferred to master.

As I said before, These days SCM is used for more than just change conflicts. It checks the quality of changes too before allowing it to be merged. A typical check these days is peer review. Peer Review means the changes made by a developer needs to be reviewed by one or more other developers before it is allowed to be merged. SCM allows the merge only when other developers has reviewed and confirmed that these changes are acceptable to be merged it. (the definition of acceptable is different in each team and project. They usually negotiate and agree between each other)

When the developer is finished with his changes, he raises a “Pull Request“. A Pull request is the way to tell other team mates that his changes is ready to be reviewed and merged.

Conclusion and Takeaway

It’s almost not-practical to build a software in a team without using SCM. Without SCM, development steps and increments are not managed properly, change conflicts can happen and cause dependency or code-loss. All this can increase the time and cost of the project and lower the transparency of development progress. Git has a simple branch-and-merge model and it is widely used by small and large software teams across the world. It has other features that help with code quality checks, history and auditing, testing and deploying the software.

How a Newly Joined Developer Affects How You Write Code

Software engineers tend to move between projects and companies quite often and working on a codebase that someone else built months or even years ago, can be quite cumbersome

There are many ways to write a piece of code. Each optimises for a metric (conciseness, readability, maintenance, performance, resource consumption, etc.).

As a general rule code should be written in a way that it’s simple, clean and readable by everyone. As a measure I always say you should write code in a way that a new developer who joins 6-months after you quit, spends minimum time to understand it.

I learnt these over different projects and teams I’ve been involved in:

Don’t make assumptions

Do not make assumptions about the knowledge and experience level of the newly joined developer (let’s call it NJD from here on). It can be a graduate student, a junior developer or a senior developer. Or someone who recently changed tech stack (e.g. from python to .NET world). Or someone who decided to become a developer after their flower-shop business didn’t take off.

So it’s best to not have any expectations and format the code in a way that is highly understandable.

Keep it close to English sentences

Isn’t it delightful when you read a block of code and understand it the very first time? As a simple measure the closer it is to an English sentence, the better it can be comprehended.

A code block can be formatted in a way that it looks like an English paragraph. Obviously it is not possible to write everything like that, But the main core logic should be written like that so that it is easily understandable.

Couple of points to help with this:

  • Remember there is no limit to number of classes, functions or files in a project.
  • Encapsulate a group of commands that do a logical task in a function with proper full name, and use that function in the main logic.
  • Name variables and functions to what they are/do completely, each word in their full form. Don’t use any short word. Remember? there is no limit in classes and files 🙂
  • Include the variable unit in the name (such as Seconds, Minutes, Utc, Kg, etc. )

Create a structure to prevent future mistakes

Remember? A new developer joined and we didn’t make any assumptions. We can leverage the code format to create a structure and prevent them from logical mistakes/errors. We can even give them hints about how to do things in a block of code. Last thing you want is that our NJD tries to fix a bug on his/her first day and a calculation goes wrong and costs money for the business 🙂 no one wants that .. It’s better when our NJD tries to fix the bug and says:

hats off to my previous developer(s) .. such a clean and readable code .. I managed to fix this bug confidently

These will help:

  • Write the code in a way to use as much intelisense and compile-time checks as you can. (Use “nameof” operator, use string interpolation)
  • Always use curly braces and indentation. Even for single statement blocks
  • Use simple comments to title each step of the logic in the block

Conclusion and Takeaway

Write the core logic in a way that it’s simple, clean and readable by everyone. Even by a developer who joins the team 6-months after you have left the company and you don’t have any assumption about their skills.

How I Do dotnet core App Setup Elegantly

Program.cs is usually one of the files that get quite messy after a while in every .NET project. From then, developers will add code on top of all that mess or even worse create a new class and reference that in.

Here’s a structure I found over years that helps me to keep app startup code readable and clean.

Generally there are 3 things to setup in Main function:

  1. Ingress appsettings and options (via appsettings files, environment variables or command line)
  2. Setup logging
  3. Setup ServiceProvider (dotnet core dependency injection)

I add Microsoft.Extensions.Hosting nuget package and use this in Main:

var hostBuilder = Host.CreateDefaultBuilder()
                   .ConfigureAppConfiguration(AddSettings)
                   .ConfigureServices(AddOptions)
                   .ConfigureServices(AddServices);
await builder.RunConsoleAsync();

CreateDefaultBuilder() creates and sets up all the 3 things above and return an IHostBuilder instance. IHostBuilder has couple of nice methods that accept lambda functions:

  • ConfigureAppConfiguration: to add configurations related to the app
  • ConfigureHostConfiguration: to add configurations related to the host itself (such as Kestrel, etc.)
  • ConfigureServices: add classes to DI

I leverage those and divide my app startup code in these three nice methods:

private static void AddSettings(IConfigurationBuilder configurationBuilder)
        {
            configurationBuilder
                .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
                .AddEnvironmentVariables();
        }

private static void AddServices(HostBuilderContext context, IServiceCollection serviceCollection)
        {
            serviceCollection
		.AddTransient<,>()
                .AddSingleton<>();
            
            serviceCollection.AddHostedService<>();
        }

private static void AddOptions(HostBuilderContext context, IServiceCollection serviceProvider)
        {
            var configuration = context.Configuration;
            
            serviceProvider.AddOptions<MyOptions>()
                .Bind(configuration.GetSection(nameof(MyOptions)))
                .ValidateDataAnnotations();
        }

So what benefits do I get?

  • Main method is clean and simple and shows the setup steps in high-level view
  • It uses Options pattern to have configurations as objects. This provides all compile time checks and intelisense features.
  • The amount of usage of stings is minimum. Therefore classes can be moved/renamed without worrying about app setup code.

What do you think?

Hello World

Photo by Negative Space on Pexels.com

My name is Arman and here is my new blog. I would like to write my thoughts about programming, software and its industry, technology in a succinct and tl;dr way. I like to-the-point posts in a way that the content can be skimmed and absorbed quickly.

My posts are live documents and I update them with the comments/reviews I get and new information I learn.

What I write here mostly applies on .NET world (especially C#) and Scrum teams.