Even if your deadline is tight, it’s still possible to write beautiful code. So, I’ve created a list of six tips to make your C# syntax elegant.
Writing code is not an easy task, and when it comes to writing quality code, it becomes even more difficult.
Something to remember is that in programming we have several ways to do something, and as long as it works, it doesn’t mean that that way is right or wrong.
But in addition to simply “working,” our application must be cohesive and contain good syntax. So, below are some examples of how to further improve your C# writing and increase the quality of your code.
Naming conventions refer to the declaration of object names. You should follow this to have nice and coherent code when naming your objects.
To declare a variable that returns a single entity/object, we use a simple name. To declare a variable that returns multiple entities/objects, it is necessary to add the suffix “s” or “List” so that we can easily identify that it will return a list of classes/objects:
//avoid
var Item = new Item();
var ItemList = new List<Item>();
//use
var item = new Item();
var items = new List<Item>();
//or
var itemList = new List<Item>();
//To declare a private variable, we use an underline (_)
//avoid
private int value = 10;
//use
private int _value = 10;
Name | Case |
---|---|
Variables | camelCase |
Class | PascalCase |
Constructor | PascalCase |
Properties | PascalCase |
Delegate | PascalCase |
Enum | PascalCase |
Arguments in Methods | camelCase |
Method | PascalCase |
Constants | PascalCase |
Field | camelCase |
We talked about how, in programming, there are several ways to do the same thing, but one thing that can always improve your code is syntax optimization. Below are some examples.
//Avoid
public ActionResult Dashboard()
{
return View();
}
//Use
public ActionResult Dashboard() => View();
var varName = "John";
//Avoid
if (varName != null && varName != "")
{
//code
}
//Use
if (!string.IsNullOrEmpty(varName))
{
//code
}
//or (In C# 9 or more)
if (varName is { Length: >0 })
{
//code
}
Test test = new Test();
//Avoid
var varName = test.Name != null ? test.Name : string.Empty;
//Use
var varName = test.Name ?? string.Empty;
Test test = new Test();
//Avoid
var details = string.Format("{0}, you are welcome, Your Id is {1}", test.Name , test.Id + "_emp");
//Use
var details = $"{test.Name}, you are welcome, Your Id is {test.Id}_emp";
//or
var details = string.Join(" ,", test.Name, "you are welcome, Your Id is", test.Id, "_emp");
string firstName = "Thomas";
string favoriteTask = string.Empty;
//Good
switch (firstName)
{
case "Jennifer":
favoriteTask = "Writing code";
break;
case "Thomas":
favoriteTask = "Writing blog post";
break;
default:
favoriteTask = "Watching TV";
break;
}
//Better
favoriteTask = firstName switch
{
"Jennifer" => "Writing code",
"Thomas" => "Writing blog post",
_ => "Watching TV",
};
With the rush of everyday life, we sometimes forget that there are methods available to validate primitive data types such as System.Int32.
When you need to do these validations, avoid using custom methods. Instead use the methods already available in the language for this.
//Avoid
public bool CheckIfIsNumber(string value)
{
bool isNumeric = true;
try
{
int i = Convert.ToInt32(value);
}
catch (FormatException ex)
{
isNumeric = false;
}
return isNumeric;
}
//Use
public bool CheckIfIsNumberic(string value) => int.TryParse(value, out int _);
One way to follow the concept of “Clean Code” and improve the readability and writing of your code in C# is to use the ternary operator “?”.
You can use it in cases where a statement checks for the possibility of a value being null—the null coalescence operator can be used to ensure that a non-null value is returned.
The code below returns the name of the contact received or the default name if the item is null. As you can see, this operator is a great choice when working with the null condition.
//Avoid
public static string CheckContactNameError(Contact contact)
{
var defaultName = "Default";
if (contact.Name != null)
{
return contact.Name;
}
else
{
return defaultName;
}
}
//Use
public static string CheckContactName(string contactName) => contactName ?? "Default";
Language-Integrated Query (LINQ) is the name for a set of technologies based on the integration of query capabilities directly into the C# language.
LINQ simplifies the queries by offering a consistent model for working with data across various kinds of sources and formats. In a LINQ query, you are always working with objects. You use the same basic coding patterns to query and transform data in XML documents, SQL databases, ADO.NET Datasets, .NET collections and any other format for which a LINQ provider is available.
Below we will get a list of “Good Prices” by going through a list of “Companies” that have “Products” with various “Market Prices”.
If the Market Price is less than 100, then we add the Product to the Good Prices list and return it at the end of the expression.
//Good
public GoodPrice GetGoodPricesGood(List<Company> companies)
{
GoodPrice goodPrices = new GoodPrice();
foreach (Company company in companies)
{
foreach (Product product in company.Products)
{
if (product.MarketValue < 100)
{
goodPrices.Products.Add(product);
}
}
}
return goodPrices;
}
//Better
public GoodPrice GetGoodPricesBetter(List<Company> companies)
{
GoodPrice goodPrices = new GoodPrice();
IEnumerable<Product> lambdaProducts = companies.SelectMany(c => c.Products).Where(p => p.MarketValue < 100);
goodPrices.Products = lambdaProducts.ToList();
//Or
//If you are not a fan of lambda expressions
var products = from company in companies
from product in company.Products
where product.MarketValue < 100
select product;
goodPrices.Products = products.ToList();
return goodPrices;
}
Setting an object’s values is very common during development and there are many ways to do this. But with this tip, you can make it simpler and more intuitive, besides making the test implementation process easier.
For this, we will use a paradigm called “Fluent Code.” It is inspired by LINQ, which we’ve already covered in this article. You can research more about “Fluent Code”—it is common to use for test projects where object filling is repeated frequently.
Let’s take an example:
//Good
public class Contact
{
public string Name { get; set; }
public string Email { get; set; }
public long Phone { get; set; }
}
public static Contact FillContactReady()
{
Contact contact = new Contact();
contact.Name = "John Smith";
contact.Email = "johnsmith@email.com";
contact.Phone = 25454471414;
return contact;
}
//Better
public class FluentContact
{
public class Contact
{
public string Name { get; set; }
public string Email { get; set; }
public long Phone { get; set; }
}
public Contact contact = new Contact();
public FluentContact AddName(string name)
{
contact.Name = name;
return this;
}
public FluentContact AddEmail(string email)
{
contact.Email = email;
return this;
}
public FluentContact AddPhone(long phone)
{
contact.Phone = phone;
return this;
}
}
public static FluentContact FillFluentContactReady()
{
return new FluentContact()
.AddName("John Smith")
.AddEmail("johnsmith@email.com")
.AddPhone(25454471414);
}
I hope that through these tips I have helped you to write clean and elegant code.
Whether you’re new to .NET or already an experienced developer, if you use these tips, you’ll certainly be recognized for writing quality code and be able to target even bigger goals. 🚀
Some code updates were published October 14, 2021, thanks to the helpful dialogue in the comments. Thanks for your feedback!