DEV Community

Cover image for My Favorite C# Features - Part 1: Strong-types, Implicit-types, Anonymous-types, and Target-types
Jeffrey T. Fritz for .NET

Posted on • Edited on

My Favorite C# Features - Part 1: Strong-types, Implicit-types, Anonymous-types, and Target-types

I've been a long-time developer and fan of the C# programming language. Heck, I even named my blog and took the nickname csharpfritz One of my favorite capabilities of the language is the immediate compiler checking and tooling support for type-checking. The instant check can save time and prevent a number of bugs in writing code quickly. With the latest updates in C# 9 and .NET 5, we now have ultimate flexibility in how types are declared and interacted with in our code. Let's review the easy ways to declare and initialize types with C#.

In the beginning, there was explicit-typing

The original versions of C# required explicit declaration of every type in your code, and it felt so redundant to type the same names over and over again:

Sandwich myBLT = new Sandwich();
myBLT.Toppings.Add("Bacon");
myBLT.Toppings.Add("Lettuce");
myBLT.Toppings.Add("Tomato");
myBLT.Bread = "Gluten-Free";

Sandwich yourSandwich = new Sandwich();
// prep your sandwich as you'd prefer
Enter fullscreen mode Exit fullscreen mode

Whether you are declaring the variable or initializing it with a class, you must explicitly declare the type assigned to the variable. Both myBLT and yourSandwich were required to have the type declaration Sandwich preceding them.

This syntax has been valid since C# v1 and is still valid today.

Enter Implicit-Typing and Initializers

The language was simplified a bit with C# 3 in 2007 when the var keyword and implicit typing was introduced. The compiler would use this keyword to infer variable types when they were initialized. The C# team also introduced initializers in C# 3, a feature that would allow you to assign properties at declaration time.

var myBLT = new Sandwich {
  Toppings = new[] {"Bacon", "Lettuce", "Tomato"},
  Bread = "Gluten-Free"
};

Sandwich yourSandwich = new Sandwich();
// prep your sandwich as you'd prefer
Enter fullscreen mode Exit fullscreen mode

The var keyword delivers no performance hit to your running code, nor does it add to compile time. It is strictly a bit of 'syntactic sugar' that makes it easier to initialize and declare variables. I've demonstrated an initializer in the above sample by setting the Bread value to "Gluten-Free" and I've introduced another feature that arrived with C# 3: an implictly-typed array of strings assigned to the Toppings property of mySandwich. The compiler determines that the array is an array of strings and assigns the type appropriately.

Types aren't for me - Anonymous Types

At the same time Implicit-Typing was introduced, the anonymous type was added to C#. With this feature, you can declare a type with a set of read-only properties.

var myBLT = new Sandwich {
  Toppings = new[] {"Bacon", "Lettuce", "Tomato"},
  Bread = "Gluten-Free"
};

Sandwich yourSandwich = new Sandwich();
// prep your sandwich as you'd prefer

var ourLunchOrder = new {
  MyItem = myBLT,
  YourItem = yourSandwich
};
Enter fullscreen mode Exit fullscreen mode

We can now inspect the outLunchOrder variable and read the properties. While anonymous types are convenient for prototyping, they shouldn't be used across namespace or memory boundaries, preferring instead to deliver a clear API to your interacting methods.

Welcome to 2021 - Target-Types

Implicit-typing forced the definition of types to the right of the equals sign when initializing a variable. Perhaps you'd prefer to keep the types on the left of the equals sign, so that all types are in the same location in your code. With C# 9 and .NET 5, this feature is now available to you and it's called Target-Typing. Let's rewrite our lunch order using this syntax:

Sandwich myBLT = new() {
  Toppings = new[] {"Bacon", "Lettuce", "Tomato"},
  Bread = "Gluten-Free"
};

Sandwich yourSandwich = new Sandwich();
// prep your sandwich as you'd prefer

var ourLunchOrder = new {
  MyItem = myBLT,
  YourItem = yourSandwich
};
Enter fullscreen mode Exit fullscreen mode

Additionally, when calling methods and passing in new objects you can use the new() keyword to create an object of the expected type:

IceCreamSundae myDessert = new();
myDessert.Toppings.Add(new() { Flavor="Chocolate" });
Enter fullscreen mode Exit fullscreen mode

Summary

The C# programming language is so flexible and allows you to take advantage of the multitude of resources in the .NET frameworks easily and in the way you want. With a smart compiler that provides access to alternate syntax that gives you the freedom to write code so that it is readable for you, I'm happier than ever to be using C#.

Over the next few weeks, I'm going to write additional entries in this series about my favorite features of C#. What do you like about the language? What do you want to see some discussion and samples of? I'll be back next week with more C# features to discuss.

Looking to get started learning C#? Checkout our free on-demand courses on Microsoft Learn! Every Monday, check out my C# with CSharpFritz live-video training series on Twitch and archived on YouTube

Top comments (1)

Collapse
 
noseratio profile image
Andrew Nosenko

A great start, tks!
Some of my most favorite recent additions to the language are using var resources = getSomethingDisposable(), the compiler support for IAsyncEnumerable, and the pattern matching features. Would be great to see more samples of the latter.