dynamic
keyword, and C# will let you make assumptions about the members of the variable. For example, if you want to declare a new Course
object, you do it like this:Course newCourse = new Course();
newCourse.Schedule();
This is, of course, assuming that you have a Course
class defined somewhere else in your program, like this:
class Course {
public void Schedule()
{
//Something fancy here
}
}
But what if you don't know what class the new object will be? How do you handle that? You could declare it as an Object
, because everything derives from Object
, right? Here's the code:
Object newCourse = new Object();
Not so fast, if you make your next line this:
newCourse.Schedule();
Note the squiggly line appears almost immediately, and you get the famous “object does not contain a definition for Schedule…” error in the design time Error List. However, you can do this:
dynamic newCourse = SomeFunction();
newCourse.Schedule();
All this code needs to have is the stub of a function that returns some value, and you are good to go. What if SomeFunction()
returns a string? Well, you get a runtime error. But it will still compile!
About now you may be thinking: “This is a good thing? How!?!” For the time being, you can blame COM. You see, COM was mostly constructed using C++, which has a variant type. In C++, you could declare a variable to be dynamic, like this:
VARIANT newCourse;
It worked just like the dynamic type, except C# wasn't invented yet. Anyway, because a lot of the objects in COM used VARIANT
out parameters, it was really tough to handle Interop using .NET. Because Microsoft Office is mostly made of COM objects, and because it isn't going to change any time soon, and because Microsoft all C# programmers to be Office developers one day, bam, you have the dynamic type.
Say, for instance, that your newCourse
is a variant out parameter from a method in a COM class. To get the value, you have to declare it an Object, like this:
CourseMarshaller cm = new CourseMarshaller(); //a COM object
int courseId = 4;
Object newCourse;
cm.MakeCourse(courseId, newCourse);
//and now we are back to square one
newCourse.Schedule(); //This causes a 'member not found exception'
Line 6 will not compile, even if the Schedule method exists, because you can't assume that newCourse
will always come back as a Course object, because it is declared a variant. You’re stuck. With a dynamic type, though, you’re golden once again, with this code:
CourseMarshaller cm = new CourseMarshaller(); //a COM object
int courseId = 4;
dynamic newCourse;
cm.MakeCourse(courseId, newCourse);
newCourse.Schedule(); //This now compiles
What happens if newCourse
comes back as something that doesn't have a Schedule method? You get a runtime error. But there are try/catch
blocks for runtime errors. Nothing will help it compile without the dynamic
keyword.
Readers who are long-time Visual Basic programmers, or even newer VB.NET programmers, realize that you can handle this dynamically — and have always been able to — in Visual Basic. Some developers recommend that programmers who work with legacy systems use Visual Basic for their new code, and this is exactly why.
In the interest of language parity, now C# can do it, too. In general, this is good, because many organizations are writing legacy code in VB and new code in C# — and it can get pretty messy in the trenches. This change makes the code base slimmer.