Why you shouldn’t use the Dynamic type in .NET

Bending the Clean Architecture Principles

Introduction

If you’re an enthusiast like myself, you will get excited when Microsoft release some sort of updates on the language, new libraries or any documentation on what is the new fancy way of doing ‘This’.

Microsoft target those releases to respond and enhance our development experience, thus each feature is the answer to a specific problem in our code. But as times goes by, new developers may question the relevance of some of these additions, and ultimately have a stand with or against them. So, is Dynamic and ExpandoObject obsolete already? Should we use them?

Why Rant :)

The idea for this article came from a PR I was recently checking, I saw my colleague using Dynamic and ExpandoObject… (Sorry R** !)

What is Dynamic

Briefly, the usage of dynamic tell the compiler to skip all checks like syntaxes and evaluate them on runtime instead:

dynamic test=new object();

test.Bark();

This code will compile normally, even though we know that object does not contain a Bark() function. This error will be shown on runtime instead.

The Problem

Just like the Async keyword, when you start using dynamic, you can’t stop. Your dynamic code will expand just like a virus and bubble up everywhere, removing one of the most underrated benefits of C# which is static types and compile-time checking…

In a way, you will start writing Python or JS in your C# code. If you really want to do that, use that other language from the beginning !

Next, Readability: You’re using an object that you cannot track with your IDE, how can you express your intent with the code you’re writing if even the compiler will skip understanding it. Even C# does not understand what you’re writing and will evaluate it on the fly so how should we ;)

As it wasn’t enough, Performance: The building and compilation phase saves a lot of time ahead of execution. This is the main difference between compiled and interpreted languages… Each one has his pros and cons but in a cloud environment when you want to squeeze every bit of performance from your app, you should also consider that.

Last but certainly not least, think about your bug hunting journeys, when a newcomer changes anything in the objects or functions. Do you really feel safe while using this feature? Even if you have unit tests, doesn’t accepting each and every possible value in your algorithm scare you? Well it should !

The Exception

If this is the case, Why did Microsoft introduce it back in 2010 ?! As discussed before each feature belong to a specific context and solve a problem. So back in the time, C# was Windows exclusive. If you remember .NET Framework (Time flies…), it was a direct competitor to java and other languages.

With the dynamic type feature, Microsoft wanted to achieve something called COM Interop. The idea was that you can integrate and run diverse applications and platforms inside C# and .NET. This was good for integrating with existing systems and scripts into your codebase.

A practical example would be that you have an existing Ruby app and you started using C# for a Desktop App. You can install a library called IronRuby and load your Ruby code INSIDE C#. So if you created a class in Ruby, you can instantiate and use it in your .NET App, which was insane !

This feature was actually made for this purpose. Nowadays with our new and portable .NET. We don’t find this very relevant most of the time and is considered a niche feature.

An Actual Exception

But there’s only a small practical scenario where I still use them… Navigating a complex JSON object. Honestly this is arguably the only context where I see this fitting even.

How to not use it

I am a huge fan of static types and compile time checking. So if I can remove dynamics and even boxing types I would find that ideal.

So as a general rule and conclusion:

  • Try to use generics, if that doesn’t work:
  • Try to use objects and boxing, if and only if it doesn’t work:
  • Your only resort is now the Dynamic type and ExpandoObject :)

But hey, at least you tried !