Example 1This first example is fairly simple. What is the difference? Well obviously one variable is type string and the other is double. But what makes the string type weak and the double type strong? The double type is more restrictive that the string type. Thus, all possible double values in myDoubleValue can also be stored with their string equivalent in myStringValue. But, not all possible values for myStringValue can be stored in myDoubleValue. We can generalize our understanding to the following statements:
- Strongly Typed objects are more restrictive than Weakly Typed objects.
- All possible values for a Strongly Type object can be represented in a Weakly Typed object. But not all possible values for the same Weakly Typed object can be represented in the Strongly Typed object.
Example 2In this example we want to access some stored values for A, B, and C. myDictionary is the weakly typed object and myClass is the strongly typed object. We can get and set our values in myDictionary via a string key. Using a MyClass type we get and set our values via the class properties. In the .NET Framework libraries, types like myDictionary are fairly common. A few examples include ASP.NET's Session, multiple ADO.NET objects like DataSet, and the XmlDocument
When should I use weakly typed objects or strongly typed objects?In most cases you should avoid weakly typed objects. Why?
Case 1Bad: Suppose we used the weakly typed object, myStringValue in Example 1 in our application. Now somewhere deep in our code myStringValue was set to a non-double like value such as "nevermind." Why was it set to that? Who knows, strange code has a way of sneaking in. When will we know that that was an error? Hopefully at least while testing the runtime of our application. But no guarantees right. You will probably find out the error when a runtime exception was throw in production.
Good: Instead, we will use myDoubleValue, the strongly typed object. Why is this better? If any code tries sneak in and set myDoubleValue = "nevermind", then we will know the error at compile time instead of runtime. Anytime we can check our code for errors at compile time is far more preferable than at runtime. Less errors in production == less costs and management headaches (that could be a lengthy discussion on its own).
Case 2Bad: What if we have in multiple places of our code some kind of logical access like if (myDictionary["A"] > 0.0d)...? Now what happens when we no longer use "A"? Again we may not know about any errors until runtime.
Good: In contrast, if we used the MyClass type instead and we had such logical code as if (myClass.A > 0.0d)..., then when we remove the property MyClass.A from our code and we compile, we will see immediately everywhere in our code errors where myClass.A is accessed.
ConclusionWeakly typed objects do have their place. For instance, within the scope of designing a framework, I believe the designers of the .NET Framework made good decisions to have some of the runtime objects as weakly typed (that would also be a lengthy discussion). However, you should avoid using weakly typed objects when you can, but there is no need to be too ridged.
One more thing (a practical example); typically in my ASP.NET applications, I will keep a single session variable, such as Session["MySession"] = new MySession(). This allows me to limit my weakly typed Session object access to a single point (one spot in my code where I will get or set the Session object). I will then define my MySession class to act as a composite structure hierarchy with all my other variables and objects pertaining to the user's session. This will keep most of my code strongly typed with some very limited weakly typed access.