The Software Purist |

Archive for February 2011

Dynamic is a new keyword that was introduced in C# 4.0. Thankfully, it hasn’t gotten a ton of press, but I can see it paving the way for all sorts of new types of abuse. By now, you’re probably familiar with my thoughts on the var keyword. Dynamic takes this one step further, by dynamically binding the class type at runtime, and determining if method calls are legal, also at runtime. Here’s an example:


public void MyMethod(dynamic param)
{
param.Call();
}

So, let’s say you pass in an instance of a class which has the method named Call. All is well, Call() will be called, albeit with a performance penalty.

Now, consider what happens if you pass in an instance of a class for which Call() doesn’t exist. It will, instead, throw an exception, which essentially states that Call() doesn’t exist for this type.

So, what’s the problem? Very simple. You’re taking a situation where you can enlist the compiler’s help, and instead pushing it off to runtime, which entails discovering it later than necessary, in some cases, much later. This increases risk and potentially increases the time to fix, since we know that at each stage later that a bug is discovered, the more expensive it is to fix. Problem 2 is that there is absolutely a performance penalty. In a lot of cases, these penalties are no so noticeable, but spread out through an entire application, they can make a serious impact. I have seen poorly written C# applications which made both heavy and improper usage of reflection that easily can operate an order of magnitude slower than well-written one which takes advantage of the type system.

Avoid dynamic in most cases. Use it for cases where it really matters. If you find yourself needing a lot of dynamic behavior, you are more well-suited to using a scripting language like Python or Ruby, where the syntax will be much cleaner and you don’t risk so much paradigm mix, therefore creating more understandable code. Otherwise, if you’re determined to use C#, then use it as the type-safe language that it can be, and don’t treat the type-system as optional, even if Microsoft got overzealous in feature overload.

What’s the solution? Instead, make the method look like this:


public interface ICall
{
void Call();
}

public void MyMethod(ICall param)
{
param.Call();
}

Using generics is also a possible solution. Just remember that when you violate the type system, you are losing the advantages of using a type-safe language.

No tags

Theme Design by devolux.nh2.me