Deep C#: Strong Typing
Written by Mike James   
Monday, 13 September 2021
Article Index
Deep C#: Strong Typing
Binding

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:

string a;

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:

a=”Hello World”;

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 and Flow of Control - Signatures

  • Type and Flow of Control - Polymorphism

  • Type and Flow of Control – Pattern Matching

  • Parameters, Type and Function Safety

 DeepCsharp180

Complications

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.

Postlude

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.

Deep C#

 Buy Now From Amazon

DeepCsharp360

 Chapter List

  1. Why C#?

    I Strong Typing & Type Safety
  2. Strong Typing
       Extract 
    Why Strong Typing
  3. Value & Reference
  4.    Extract Value And Reference
  5. Structs & Classes
       Extract
    Structs & Classes 
  6. Inheritance
      
    Extract
    Inheritance
  7. Interfaces & Multiple Inheritance
      
    Extract Interface
  8. Controlling Inheritance
    II Casting & Generics
  9. Casting - The Escape From Strong Typing
      
    Extract Casting I ***NEW!
  10. Generics
  11. Advanced Generics
  12. Anonymous & Dynamic
    Typing
    III Functions
  13. Delegates
  14. Multicast Delegates
  15. Anonymous Methods, Lambdas & Closures
    IV Async
  16. Threading, Tasks & Locking
  17. The Invoke Pattern
  18. Async Await
  19. The Parallel For
    V Data - LINQ, XML & Regular Expressions
  20. The LINQ Principle
  21. XML
  22. LINQ To XML
  23. Regular Expressions
    VI Unsafe & Interop
  24. Interop
  25. COM
  26. Custom Attributes
  27. Bit Manipulation
  28. Advanced Structs
  29. Pointers 

Extra Material

 <ASIN:1871962714>

 <ASIN:B09FTLPTP9>

 

To be informed about new articles on I Programmer, sign up for our weekly newsletter, subscribe to the RSS feed and follow us on Twitter, Facebook or Linkedin.

Banner


TypeScript Improves Never-Initialized Variables Checks
21/10/2024

Microsoft has announced TypeScript 5.7 in beta, with improvements including stronger checks for variables that have never been initialized before use, and path rewriting for relative paths.



Extend NGINX With The New JavaScript Module
28/10/2024

Inject middleware functionality into NGINX with the expressive power of Javascript. NGINX JavaScript or NJS for short is a dynamic module under which you can use scripting for hooking into the NGINX e [ ... ]


More News

espbook

 

Comments




or email your comment to: comments@i-programmer.info



Last Updated ( Monday, 04 October 2021 )