C# 8 : Using Declaration

The next feature we would explore in C# 8 is more off a syntatic sugar, but neverthless it is important to understand the difference between the new syntax and the original feature it is covering up. We are all aware of the Using statements, which allows correct usage of the IDisposible objects.

Using Statement

Let us begin by writing an example with the Old way of doing things. We will first introduce our Custom Object with IDisposible implemented.

public interface ITalk
{
void Talk(string message);
}

public class CustomDisposibleObject : IDisposable,ITalk
{
public void Dispose()
{
Console.WriteLine($"Disposing {nameof(CustomDisposibleObject)}");
}

public void Talk(string message)
{
Console.WriteLine($"{nameof(CustomDisposibleObject)}-{nameof(ITalk.Talk)} : {message}");
}
}

We will now use CustomDisposibleObject with the Using Statement.

public int UsingStatement()
{
using (var customDisposibleObject = new CustomDisposibleObject())
{
customDisposibleObject.Talk(nameof(IExample.UsingStatement));
return default;
}
}

The Using statement is of course a syntatic sugar over the Try-Finally block. The compiler translates the above code as (check using Telerik’s JustDecompile)

public int UsingStatement()
{
int num;
CustomDisposibleObject customDisposibleObject = new CustomDisposibleObject();
try
{
customDisposibleObject.Talk("UsingStatement");
num = 0;
}
finally
{
if (customDisposibleObject != null)
{
customDisposibleObject.Dispose();
}
}
return num;
}

So far, so good. So what is the real problem with the Using Statement and why would one introduce the Using Declaration. To begin with, the Using Statement syntax is way too verbose and breaks the normal flow of syntax. This is where the Using Declaration comes into picture.

Using Declaration

The Using Declaration Sytax removes much of the ceremony associated with the Using Statement blocks. For example, if one were rewrite the above code via the new Using Declaration.

public int UsingDeclaration()
{
using var customDisposibleObject = new CustomDisposibleObject();
customDisposibleObject.Talk(nameof(IExample.UsingDeclaration));
return default;
}

The cerimonial braces are now gone and the code look less verbose. The obvious question would be – When is the object disposed ?

The object is disposed when it leaves the scope, which in the case of the code above is the method.

So how does the new syntax gets translated by the compiler ? Let us rerun the JustDecompile and check it.

public int UsingDeclaration()
{
int num;
CustomDisposibleObject customDisposibleObject = new CustomDisposibleObject();
try
{
customDisposibleObject.Talk("UsingDeclaration");
num = 0;
}
finally
{
if (customDisposibleObject != null)
{
customDisposibleObject.Dispose();
}
}
return num;
}

As you can observe, there is no difference at all. The new syntax removes the cerimonial braces, making the code look less nested.

Sample Code for this article could be found in my Github.

SOLID: Interface Segregation Principle

Completion of the series of articles on SOLID Principles has been due for a long time now. The lockdown due to Covid-19 has atleast given me more time to be able to work one some of the due items.

In this part of the series we will seek to know more about the “I” of SOLID, the Interface Segregation Principle (ISP). To understand the ISP better, we will begin by visiting a scenario where things have/could go wrong.

Consider we begin writing code for a Printer. We define the interface as follows

public interface IPrinter
{
void Printer();
void Scan();
void Copy();
}

public class AllInOnePrinter:IPrinter
{
public void Print()
{

}
public void Scan()
{

}
public void Copy()
{

}
}

This seems perfectly fine when we are considering the All-In-One Printers, but we still got to support the economic printers which do not have Scanners. A implementation of EconomicPrinterwould look like following

public class EconomicPrinter:IPrinter
{
public void Print()
{

}
public void Scan()
{
throw new NotImplementedException();
}
public void Copy()
{
throw new NotImplementedException();
}
}

The problems with the implementations just stares at our face in the implementation of EconomicPrinter. The particular printer which do not support the Scan() and Copy() functionality is forced to implement the method just because the interface has it. This paves way for possible violation of Liskov Substition Principle.

This kind of polluted interface is known as a Fat interface(or interface bloat), where an interface incorporates way too many features, only to find that most the clients do not support all the features.

The problems with Fat interfaces or violations of ISP are more visible in cases where each of the implementation of the interface is in separate assemblies. Now for a change in the interface, each of the assemblies has to be rebuild even if there is no visible change in their functionality.

Interface Segregation Principle

That brings use the definition of Interface Segregation Principle, formally defined as

“Clients should not be forced to depend upon interfaces that they do not use.”

Quite similar to the Single Responsibility Principle, the ISP aims to reduce the impact of changes by splitting the responsibilities.

Following the Interface Segregation Principle, we split the IPrinter interface into smaller interfaces. For example

public interface IPrinter
{
void Print();
}

public interface ICanScan()
{
void Scan();
}

public interface ICanCopy()
{
void Copy();
}

Now the EconomicPrinter needs to implement only the interface which it provides support for.

public class EconomicPrinter:IPrinter
{
public void Print()
{

}
}

While the All-in-One printer can provide all the additional features via the newly defined interfaces.

public class AllInOnePrinter:IPrinter,ICanCopy, ICanScan
{
public void Print()
{

}
public void Scan()
{

}
public void Copy()
{

}
}

Please note this doesn’t mean all the interface should have only one method. No, that is definitely not true. The trick lies in understanding the responsibilities of interface and expected behaviors of the Clients.

That is all about ISP. We will delve into the final article on SOLID (Dependency Injection shortly)

C# 8 : Index and Range

While C# as a language has grown leaps and bounds, one are that was least addressed was manipulation of collections (arrays in particular). C# 8 looks to change exactly that by introducing two new Types.

System.Index

System.Index is a structure that can be used to Index a collection either from the start or the end. In previous versions of the language, there was no direct way to index a collection from the end. For example,

// Get the 2nd element from end in the array
var secondElementFromLast = arr[arr.Length-2];

This changes with introduction of the System.Index, which fortunately is introduced with its own syntatic sugar. The code above, for accessing the second last element could be now rewritten as

// Get the 2nd element from end in the array
var secondElementFromLast = arr[^2]; // With the uniary prefix 'hat' operator

To access the elements from the begining of the array, you could use

// Get 2nd element from the start in the array
var secondElementFromStart = arr[2]; // No changes here

System.Range

In previous versions of C#, there was no easy way to get a slice of the collection. Let’s say, you wanted to get all elements from 2nd to 5th element in the array. You could achieve this using Linq using the Enumerable.Skip and Enumerable.Take methods. For example

var slice = list.Skip(1).Take(4);

C# 8.0 introduces the System.Range type, again with support of syntatic sugar to ease the life of developers. The above code could now be rewritten as

var slice = list[1..5];

The Range Structure represents range that has a start and end indexes and is represented by binary infix x..y. Do note that both operands of the range could be ommited to provide different meanings. For example

var slice1 = list[5..]; // All elements starting from the 5th element in collection
var slice2 = list[..5]; // First 5 elements in collection
var slice3 = list[..^5]; // Elements starting from first till the 5th element from last
var slice4 = list[^5..]; // Last 5 elements in collection
var slice5 = list[..]; // Entire List

We will continue exploring newer features of the language in coming blog posts.

Automapper – Use IoC for creating Destinations

Automapper by default creates new instances of destination using the default contructor. If you need to ask the IoC to create the new instance, it actually turns out to be pretty simple.
We will begin by setting up our Unity Container to register the IMapper.

var mapper = MappingProfile.InitializeAutoMapper(_unityContainer).CreateMapper();

_unityContainer.RegisterInstance<IMapper>(mapper);

As you can see, you are also initializing the Automapper with certain configurations. Let’s see what exactly it is. Following is the definition of MapperProfile.

public static class MappingProfile
{
public static MapperConfiguration InitializeAutoMapper(IUnityContainer container)
{
MapperConfiguration config = new MapperConfiguration(cfg =>
{
cfg.ConstructServicesUsing(type => container.Resolve(type));
cfg.AddProfile(new AssemblyProfile());
});
return config;
}
}

As you can observe, you are configuring the Automapper to Construct using the IUnityContainer. The following line does the magic for you as it uses the existing Container to create new instances (if registered with IoC) each time Automapper finds a particular type in destination.

cfg.ConstructServicesUsing(type => container.Resolve(type));

In the next blog post, we will investigate Automapper in bit more deeply. For now, please refere the sample code demonstrating the blog post at my Github