|Deep C#: Strong Typing|
|Written by Mike James|
|Monday, 13 September 2021|
Page 2 of 2
Static Typing and Binding
Even with strong typing we have a choice of how to implement it. We can opt to have a variable declared just once as one particular type that persists for the entire life of the program. That is, following:
you can be sure that wherever you see a in the program it references a string. Of course, things are not quite this simple as local variables can reuse the same name in another part of the program and there may well be a variable called a that references something that isn’t a string. However, with these scope and lifetime issues taken into account, we can be sure that when a occurs in the program with its original meaning, i.e. it is in scope, then it is a string.
This is static typing and the alternative is dynamic typing where a variable can be declared to be a different type or more usually can acquire a new type implicitly by being assigned to that type. In this approach you can even dispense with the idea that a variable has a type as it can clearly be made to reference anything you like.
C# uses, mostly, static typing. This may seem like a small decision but it actually has far reaching consequences for the language. In particular static typing makes early binding the natural choice. The idea of binding is confusing and generally poorly defined. It basically is about when a variable acquires its reference or, more accurately, when its reference is determined. For simple cases early binding, i.e. binding at compile time, is not only obvious, it seems the only option. For example, if you write:
It is very obvious that a is a string and it references a string literal and this is determined at compile time. The variable a is early-bound to its reference.
It almost seems as if late binding is a silly idea – why would you ever put off binding a variable to its reference? Consider the case where we have two classes MyClassA and MyClassB that is derived from it. Both have a myMethod method, but MyClassB has overridden it and provides its own version of the method. Now consider what happens in:
MyClassA myObject; myObject=anObject; myObject.myMethod();
where anObject is either a MyClassA or a MyClassB. This is perfectly legal and type safe as MyClassA and MyClassB have a myMethod attribute. However, it raises the question of which of the versions of the method should be called?
If you use early binding then myObject.myMethod should be bound at compile time to the MyClassA version as this is the variable’s declared type. If you use late binding then it could be either of the versions depending on what anObject is at run time.
Early binding only depends on the declared type of the variable. Late binding depends on the type of the object referenced at run time.
Notice that only the early binding version strictly satisfies the Liskov principle as only it guarantees that the method used is always the same, independent of the actual type of the object.
In C# early binding is the default but you can opt for late binding, see Virtual Functions in Chapter 4.
Included in chapter but not in this extract
Type safety is an idea that seems good and cost-free when you first start applying it to simple situations, but as things become more like the real world, problems start to arise. Mostly these problems are to do with having to write more code that you would need without strong typing. In an effort to fix these problems new features have been added to the language. They include generics (see Chapter 8), optional late binding and virtual methods (see Chapter 4), interfaces, pattern matching and variance.
How you view these features depends very much on how you view the advantages of strong static typing. There is no doubt that while they may solve problems, such problems only arise in complex situations and can be difficult to understand.
So much is promised for type-safe code, but you have to see that in many senses it only solves a very simple problem – that the methods and properties that you use actually exist on the object you are working with. This is something worth having, but it can be achieved in many different ways. At the end of the day, code often has to determine the type of an object at run time and when this happens in a strongly typed language we have to resort to many complex techniques to make it work.
Buy Now From Amazon
or email your comment to: firstname.lastname@example.org
|Last Updated ( Tuesday, 14 September 2021 )|