Sharing With Passion

February 05, 2013

Posted by Sabar Santoso in , , , | February 05, 2013 No comments



Dynamic features defer decisions until runtime. For example, in a language that supports dynamic method invocation, the business of working out exactly which method to run doesn’t happen until the program gets to the point where it tries to invoke the method. This means that dynamic code doesn’t necessarily do the same thing every time it runs—a particular piece of code might end up invoking different methods from time to time.What exactly is the difference between static and dynamic? 

The terminology is slightly confusing because C# has a keyword called static which is unrelated, so you’ll need to put your knowledge of that static to one side for now. When it comes to the dynamic/static distinction, something is dynamic if it is decided at runtime, whereas a static feature is determined at compile type. If that sounds rather abstract, it’s because the distinction can apply to lots of different things, including the choice of which method to call, the type of a variable or an expression, or the meaning of an operator. Let’s look at some concrete examples. The compiler is able to work out quite a lot of things about code during compilation, even code as simple as Example 1 :

Example 1 : Simple code with various static featuresvar myString = Console.ReadLine();var modifiedString = myString.Replace("color", "colour");

We’ve used the var keyword here, so we’ve not told the compiler what type these variables have, but it can work that out for us. The Console.ReadLine() method has a return type of string, meaning that myString must be of type string—the variable’s type can never be anything else, and so we say that it has a static type. (And obviously, the same would be true for any variable declared with an explicit type—declaring myString explicitly as a string would have changed nothing.) Likewise, the compiler is able to work out that modifiedString is also a string. Any variable declared with var will have a static type.

The compiler determines other aspects of code statically besides the types of variables. For example, there are method calls. The Console.ReadLine() call is straightforward. Console is a class name, so our code has been explicit about where to find the method. Since there’s no scope for ambiguity over which method we mean, this is a static method invocation—we know at compile time exactly which method will be called at runtime. The myString.Replace method is slightly more interesting: myString refers to a variable, not a class, so to understand which method will be invoked, we need to know what type myString is. But as we already saw, in this example, its type is known statically to be string. As it happens, there are two overloads of Replace, one that takes two string arguments and one that takes two char arguments. In this code, we are passing to string literals, so the argument types are also known statically. This means that the compiler can work out which overload we require, and bakes that choice into the compiler output—once compilation completes, the exact method that Example 18-1 invokes is fixed. All the decisions are made at compile time here, and nothing can change the decision at runtime, and this is the nature of the static style. 

You might be thinking that we’ve seen C# features in earlier chapters that enable this. And you’d be right: virtual methods, interfaces, and delegates all provide us with ways of writing code which picks the exact method to run at runtime. Static/dynamic is more of a continuum than a binary distinction. Virtual methods are more dynamic than nonvirtual methods, because they allow runtime selection of the method. Interfaces are more dynamic than virtual methods, because an object does not have to derive from any particular base class to implement a particular interface. Delegates are more dynamic than interfaces because they remove the requirement for the target to be compatible with any particular type, or even to be an object—whereas virtual methods and interfaces require instance methods, delegates also support those marked with the static keyword. (Again, try not to get distracted by the overlap in terminology here.)
As you move through each of these mechanisms, the calling code knows slightly less about called code—there’s more and more freedom for things to change at runtime. 

However, these mechanisms all offer relatively narrow forms of dynamism. The distinctions just listed seem rather petty next to a language that wholeheartedly embraces a dynamic style. JavaScript, for example, doesn’t even require the caller to know exactly how many arguments the method is expecting to receive.* And in Ruby, it’s possible for an object to decide dynamically whether it feels like implementing a particular method at all, meaning it can decide at runtime to implement methods its author hadn’t thought to include when originally writing the code!

0 comments:

Post a Comment

Silahkan Isi Komentar Anda :

Search

Bookmark Us

Delicious Digg Facebook Favorites More Stumbleupon Twitter