One of the lesser known features of C# is the ability to create implicit and explicit user-defined type conversions, meaning we have support for both implicit and explicit conversions of one type to another type. We also have explicit and implicit operators, meaning some operators require an explicit cast and some operators don’t.
This article talks about these explicit and implicit conversion operators and how we can work with them in C#. To work with the code examples provided in this article, you should have Visual Studio 2019 installed in your system. If you don’t already have a copy, you can download Visual Studio 2019 here.
Create a console application project in Visual Studio
First off, let’s create a .NET Core console application project in Visual Studio. Assuming Visual Studio 2019 is installed in your system, follow the steps outlined below to create a new .NET Core console application project in Visual Studio.
- Launch the Visual Studio IDE.
- Click on “Create new project.”
- In the “Create new project” window, select “Console App (.NET Core)” from the list of templates displayed.
- Click Next.
- In the “Configure your new project” window shown next, specify the name and location for the new project.
- Click Create.
Following these steps will create a new .NET Core console application project in Visual Studio 2019. We’ll use this project in the subsequent sections of this article.
What are implicit and explicit type conversions?
An implicit type conversion is one that is done by the runtime automatically. You don’t need to cast to any specific type. Here is an example that illustrates an implicit conversion:
int x = 100;
double d = x;
However, note that the following code will not compile.
double d = 100.25;
int x = d;
Here's the error you'll observe In Visual Studio on compilation of the above code snippet.
Figure 1. The compiler won’t let you assign a double to an integer variable in C#.
The error indicates that the runtime will not convert a double to an int without explicit type casting. This type of type casting is known as explicit type casting because you must write explicit code to perform the type casting.
You can fix the non-compilable code snippet by specifying an explicit type cast of double to int as shown in the code snippet below.
int x = 100;
double d = (int) x;
The above code will compile successfully without any errors.
Create model and DTO classes in C#
Let’s now understand how we can use implicit and explicit conversions in user-defined data types, i.e., classes.
Consider the following two classes.
public class Author
{
public Guid Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
public class AuthorDto
{
public string Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
In the preceding code snippet, the Author class is the model, i.e., it represents the Author entity. The AuthorDto class represents the data transfer object of the Author class. A data transfer object is a container of data used to pass data between the layers of an application.
Convert model to DTO and vice-versa in C#
The following two methods show how you can convert an Author instance to an AuthorDto instance and vice-versa.
public AuthorDto ConvertAuthorToAuthorDto(Author author)
{
AuthorDto authorDto = new AuthorDto
{
Id = author.Id.ToString(),
FirstName = author.FirstName,
LastName = author.LastName
};
return authorDto;
}
public Author ConvertAuthorDtoToAuthor(AuthorDto authorDto)
{
Author author = new Author
{
Id = Guid.Parse(authorDto.Id),
FirstName = authorDto.FirstName,
LastName = authorDto.LastName
};
return author;
}
If you need to write such conversion code for several classes in your application, you will not only find it cumbersome but also your code will not have proper readability. Here is where implicit and explicit conversion operators come in.
Use the implicit conversion operator in C#
A better way to achieve the model-DTO conversions illustrated above is to use implicit and explicit operators. When you use implicit or explicit conversion operators, you don’t have to write cumbersome methods to convert an instance of one type to another. The code is much more straightforward.
The following code snippet shows how you can take advantage of the implicit operator to convert an Author instance to an AuthorDto instance.
public static implicit operator AuthorDto(Author author)
{
AuthorDto authorDto = new AuthorDto();
authorDto.Id = author.Id.ToString();
authorDto.FirstName = author.FirstName;
authorDto.LastName = author.LastName;
return authorDto;
}
And here's how you can use the implicit operator to convert an Author instance to an AuthorDto instance:
static void Main(string[] args)
{
Author author = new Author();
author.Id = Guid.NewGuid();
author.FirstName = "Joydip";
author.LastName = "Kanjilal";
AuthorDto authorDto = author;
Console.ReadKey();
}
Use the explicit conversion operator in C#
The following code snippet shows how you can take advantage of the explicit operator to convert an Author instance to an instance of AuthorDto class.
public static explicit operator AuthorDto(Author author)
{
AuthorDto authorDto = new AuthorDto();
authorDto.Id = author.Id.ToString();
authorDto.FirstName = author.FirstName;
authorDto.LastName = author.LastName;
return authorDto;
}
In this case you’ll need an explicit cast to convert an Author instance to an AuthorDto instance as shown in the code snippet given below.
static void Main(string[] args)
{
Author author = new Author();
author.Id = Guid.NewGuid();
author.FirstName = "Joydip";
author.LastName = "Kanjilal";
AuthorDto authorDto = (AuthorDto)author;
Console.ReadKey();
}
Note you cannot have both implicit and explicit operators defined in a class. If you have defined an implicit operator, you will be able to convert objects both implicitly and explicitly. However, if you have defined an explicit operator, you will be able to convert objects explicitly only. This explains why you cannot have both implicit and explicit operators in a class. Although an implicit cast is more convenient to use, an explicit cast provides better clarity and readability of your code.
How to do more in C#:
- Singleton vs. static classes in C#
- How to log data to the Windows Event Log in C#
- How to use ArrayPool and MemoryPool in C#
- How to use the Buffer class in C#
- How to use HashSet in C#
- How to use named and optional parameters in C#
- How to benchmark C# code using BenchmarkDotNet
- How to use fluent interfaces and method chaining in C#
- How to unit test static methods in C#
- How to refactor God objects in C#
- How to use ValueTask in C#
- How to use immutability in C
- How to use const, readonly, and static in C#
- How to use data annotations in C#
- How to work with GUIDs in C# 8
- When to use an abstract class vs. interface in C#
- How to work with AutoMapper in C#
- How to use lambda expressions in C#
- How to work with Action, Func, and Predicate delegates in C#
- How to work with delegates in C#
- How to implement a simple logger in C#
- How to work with attributes in C#
- How to work with log4net in C#
- How to implement the repository design pattern in C#
- How to work with reflection in C#
- How to work with filesystemwatcher in C#
- How to perform lazy initialization in C#
- How to work with MSMQ in C#
- How to work with extension methods in C#
- How to us lambda expressions in C#
- When to use the volatile keyword in C#
- How to use the yield keyword in C#
- How to implement polymorphism in C#
- How to build your own task scheduler in C#
- How to work with RabbitMQ in C#
- How to work with a tuple in C#
- Exploring virtual and abstract methods in C#
- How to use the Dapper ORM in C#
- How to use the flyweight design pattern in C#