Languages: strongly typed, weakly typed, dynamic, and static

The C# language is a strongly typed language: this means that any attempt to pass a wrong kind of parameter as an argument, or to assign a value to a variable that is not implicitly convertible, will generate a compilation error. This avoids many errors that only happen at runtime in other languages.

In addition, by dynamic, we mean those languages whose rules are applied at runtime, while static languages apply their rules at compile time. JavaScript or PHP are good examples of the former case, and C/C++ of the latter. If we make a graphic representation of this situation, we might come up with something like what is shown in the following figure:

Languages: strongly typed, weakly typed, dynamic, and static

In the figure, we can see that C# is clearly strongly typed, but it's much more dynamic than C++ or Scala, to mention a few. Of course, there are several criteria to catalog languages for their typing (weak versus strong) and for their dynamism (dynamic versus static).

Note that this has implications in the IDE as well. Editors can tell us which type is expected in every case, and if you use a dynamic declaration such as var, the right side of the equality (if any) will be evaluated, and we will be shown the calculated value for every declaration:

Languages: strongly typed, weakly typed, dynamic, and static

Even outside of the .NET world, Visual Studio's IDE is now able to provide strongly typed and Intellisense experiences when using languages such as TypeScript, a superset of JavaScript that transpiles (converts into) pure JavaScript but can be written using the same coding experience as what we would have in C# or any other .NET language.

It's available as a separate type of project, if you're curious about it, and the latest up-to-date version is TypeScript 2.0, and it was recently published (you can take a look at a detailed description of its new capabilities at https://blogs.msdn.microsoft.com/typescript/).

As we'll see later in this chapter, Intellisense is key for the LINQ syntax, in which many expressions return a new (non-existing) type, which can be automatically assigned to the correct type by the compiler if we use a var declaration.

The main differences

So, going back to the title, what made C# different? I'll point out five core points:

  • Everything is an object (we mentioned this in Chapter 1, Inside the CLR). Other languages, such as Smalltalk, Lisp, among others, have done this earlier, but due to different reasons, the performance penalty was pretty hard.
  • As you know, it's enough to take a look at the Object Explorer to be able to check where an object comes from. It's a good practice to check the very basic values, such as int or String, which are nothing but aliases of System.Int32 and System.String, and both come from object, as shown in the following screenshot:
    The main differences
  • Using the Boxing and Unboxing techniques, any value type can be converted into an object, and the value of an object can be converted into a simple value type.
  • These conversions are made by simply casting the type to an object (and vice versa) in this manner:
    // Boxing and Unboxing
    int y = 3; // this is declared in the stack
    // Boxing y in a Heap reference z
    // If we change z, y remains the same.
    object z = y;
    // Unboxing y into h (the value of
    // z is copied to the stack)
    int h = (int)z;

Using Reflection (the technique that allows you to read a component's metadata), an application can call itself or other applications, creating new instances of their containing classes.

  • As a short demo, this simple code launches another instance of a WPF application (a very simple one with just one button, but that doesn't matter):
    static short counter = 1;
    private void btnLaunch_Click(object sender, RoutedEventArgs e)
    {
      // Establish a reference to this window
      Type windowType = this.GetType();
      // Creates an instance of the Window
      object objWindow = Activator.CreateInstance(windowType);
      // cast to a MainWindow type
      MainWindow aWindow = (MainWindow)objWindow;
      aWindow.Title = "Reflected Window No: " + (++counter).ToString();
      aWindow.Show();
    }
  • Now, every time we click on the button, a new instance of the window is created and launched, indicating its creation order in the title's window:
    The main differences
  • You can have access to other components through a technology called Platform Invoke, which means you can call operating systems' functions by importing the existing DLLs using the DllImport attribute:
    • For instance, you can make an external program's window the child of your own window using the SetParent API, which is part of User32.dll, or you can control operating system events, such as trying to shut down the system while our application is still active.
    • Actually, once the permissions are given, your application can call any function located in any of the system's DLL if you need access to native resources.
    • The schema that gives us access to these resources looks like what is shown in the following figure:
      The main differences
    • If you want to try out some of these possibilities, the mandatory resource to keep in mind is http://www.PInvoke.net, where you have most of the useful system APIs, with examples of how to use them in C#.
    • These interoperation capabilities are extended to interactions with applications that admit Automation, such as those in the Microsoft Office Suite, AutoCAD, and so on.
  • Finally, unsafe code allows you to write inline C code with pointers, perform unsafe casts, and even pin down memory in order to avoid accidental garbage collection. However, unsafe does not mean that it is unmanaged. Unsafe code is deeply tied into the security system.
    • There are many situations in which this is very useful. It might be an algorithm that's difficult to implement or a method whose execution is so CPU-intensive that performance penalties become unacceptable.

While all this is important, I was surprised by the fact that every event handler in C# (as also in other .NET languages) would have two and only two arguments. So, I asked Anders about it, and his answer was one of the most clear and logical ones that I've ever heard.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.118.7.102