Controlling Type conversion in C#

You can become a serverless blackbelt. Enrol in my course Learn you some Lambda best practice for great good! and learn best practices for performance, cost, security, resilience, observability and scalability. By the end of this course, you should be able to make informed decisions on which AWS service to use with Lambda and how to build highly scalable, resilient and cost efficient serverless applications.

Ever run into a situation where your application needs to use a type for its internal working but occasionally need to convert that type into another just so it can be passed to another application which doesn’t understand some of the base types we have in the .Net space?

Consider the example below, where the Player is a type in my problem domain, but I need to communicate information about the player with a non-.Net client which doesn’t have the Guid type, so I need to have a PlayerDTO type used exclusively for message passing:

public sealed class Player
    public Player(string name, long score)
        Name = name;
        Score = score;
        ID = Guid.NewGuid();

    public string Name { get; private set; }
    public Guid ID { get; private set; }
    public long Score { get; private set; }

public sealed class PlayerDTO
    public PlayerDTO(string name, long score, string id)
        Name = name;
        Score = score;
        ID = id;

    public string Name { get; private set; }
    public string ID { get; private set; } // client is not .Net based so no Guid there
    public long Score { get; private set; }

The problem here is that there is no easy way to convert the Player type to PlayerDTO and every time I want to create a new PlayerDTO object I need to manually copy the values from Player into PlayerDTO’s constructor, and my application needs to know that it needs to convert Player.PlayerID into a string.

A cleaner solution here is to overload either the implicit or explicit converter so you can simply cast a Player object into a PlayerDTO object:

// Overload explicit cast converter to allow easy conversion from a Winner to WinnerAmfvo object
public static explicit operator PlayerDTO(Player player)
    return new PlayerDTO(player.Name, player.Score, player.PlayerID.ToString());

Further more, this allows you to easily convert an array of Player objects into an array of PlayerDTO objects:

// use Array.ConvertAll
PlayerDTO[] playerDTOs = Array.ConvertAll(players, p => (PlayerDTO) p);
// use Linq
playerDTOs = players.Select(p => (PlayerDTO) p).ToArray();

No Interface types allowed

One thing to bear in mind when using the implicit/explicit operators is that you won’t be able to use interface types, and the reason is specified in Section 10.9.3 of the C# spec.

In short, defining an implicit or explicit conversion between reference types gives the user the expectation that there will be a change in reference; after all, the same reference cannot be both types. On the other hand, the user does not have the same expectation for conversions between reference types and interface types.

In these cases, you still have other ways to make type conversion cleaner and centralised, for example:

Create a FromIPlayer method

playerDTOs = iPlayers.Select(p => PlayerDTO.FromPlayer(p)).ToArray();

Put all conversions in a PlayerConvert static object

If you have lots of types which can be converted to many types then it might be a cleaner solution to just put all the conversions into one static object, like the System.Convert class. You then use it like this:

playerDTOs = iPlayers.Select(p => PlayerConvert.ToPlayerDTO(p)).ToArray();


StackOverflow question on why you can't use interface types with implicit/explicit operator
Liked this article? Support me on Patreon and get direct help from me via a private Slack channel or 1-2-1 mentoring.
Subscribe to my newsletter

Hi, I’m Yan. I’m an AWS Serverless Hero and the author of Production-Ready Serverless.

I specialise in rapidly transitioning teams to serverless and building production-ready services on AWS.

Are you struggling with serverless or need guidance on best practices? Do you want someone to review your architecture and help you avoid costly mistakes down the line? Whatever the case, I’m here to help.

Hire me.

Check out my new podcast Real-World Serverless where I talk with engineers who are building amazing things with serverless technologies and discuss the real-world use cases and challenges they face. If you’re interested in what people are actually doing with serverless and what it’s really like to be working with serverless day-to-day, then this is the podcast for you.

Check out my new course, Learn you some Lambda best practice for great good! In this course, you will learn best practices for working with AWS Lambda in terms of performance, cost, security, scalability, resilience and observability. We will also cover latest features from re:Invent 2019 such as Provisioned Concurrency and Lambda Destinations. Enrol now and start learning!

Check out my video course, Complete Guide to AWS Step Functions. In this course, we’ll cover everything you need to know to use AWS Step Functions service effectively. There is something for everyone from beginners to more advanced users looking for design patterns and best practices. Enrol now and start learning!

Are you working with Serverless and looking for expert training to level-up your skills? Or are you looking for a solid foundation to start from? Look no further, register for my Production-Ready Serverless workshop to learn how to build production-grade Serverless applications!

Find a workshop near you