Using Dynamic Typing When an Interface was Needed

Interfaces and base classes allow us a great deal of power in object oriented programming. We are able to accept a base type or interface and be given an implementation or an inheritor and continue working correctly. What if, however, we need to be able to accept more than one type, which have the same methods or properties, but to not share an interface or base class? Often the best answer is to add a common interface to these, so that the shared behavior is defined. In most of my cases when I need to do something like this, it is because I don’t have the source code for one or more of the classes.

Our answer in this case is the dynamic types which we added in to C# 4.0. In this new revision of the language, we are able to declare an object deferring its type until runtime. We will define how we will use the object now, and at runtime our code will attempt to use that object.

The following is some example code showing how to use the dynamic keyword to use two classes interchangeably:

class Program
{
public static List<DateTime>
Dates = new List<DateTime>();

static void Main(string[] args)
{
var someClass = new SomeClass(DateTime.Now);
GetEventDate(someClass);
var otherClass = new OtherClass(DateTime.Now);
GetEventDate(otherClass);

var values = Dates.Select(d => d.ToShortDateString());
Console.WriteLine(string.Join("---", values));
}

private static void GetEventDate(dynamic objectWithDate)
{
Dates.Add(objectWithDate.Date);
}
}

public class SomeClass
{
public DateTime Date { get; set; }

public SomeClass(DateTime date)
{
Date = date;
}
}

public class OtherClass
{
public DateTime Date { get; set; }

public OtherClass(DateTime date)
{
Date = date;
}
}

So in this example, if we say that I didn’t have access to OtherClass in order to give it some interface, using the dynamic would allow me to get around this and use a convention-based approach to development. When the alternative is some cluttered approach, I am always in favor of simplifying the readability and usability of my source code. Now there is less of a reason to complain that a certain class from a library or generated code doesn’t implement an interface. (There is still reason, but at least we can avoid some of the issues at play.)

Comments