Jagged Arrays

Jagged arrays is a one of built-in data structure in .Net framework where all the elements of the data structure are of same type.  Though it seems simple, but it can easily become puzzling when mixed with other array structures. In this blog, I will try to solve this puzzle.

Lets start with a simple jagged array:

int[][] simple = new int[2][] {new int[] {2, 3, 4}, new int[] {5, 6, 7, 8}};

In above statement we declared an array, where each element of the array is itself an array of integers. As part of initialization, we declared the size of first array as 2. First element of this array is further initialized with array of size 3 (2,3,4) and second element is initialized with array of size 4 (5,6,7,8).

Lets make it complex:

 int[,][] complex;

Whats the outcome of above statement. Well there are two possibilities:
a) We are declaring a single dimension array where each element is itself a matrix of integers:
b) We are declaring a matrix where each element of matrix is itself an array of integers.

The correct answer is b. The above statement will create a matrix where each element is a array by itself. Following code snippet will combine the declaration and initialization of same structure.

int[,][] complex = new int[2, 2][] 
                  { 
                     { new int[] { 1 }, new int[] { 2, 3 } }, 
                     { new int[] { 4, 5, 6 }, new int[] { 7,8,9,10 } } 
                  };

In above code we declared a matrix of 2×2. Element at [0,0] is an array of size 1 (1). Element at [0,1] is an array of size 2 (2,3). Element at [1,0] is an array of size 3 with values (4,5,6) and last element [1,1] is an array of size 4 with values (7,8,9,10).

Lets make it more complex.

int[,][,] moreComplex;

By following the same convention, it is matrix where each element of the matrix is a matrix of integers. Following code will declare and initialize matrix of matrix:

int[,][,] moreComplex = new int[2,2][,]
                                    {
                                     {
                                      new [,] {{11,12},{13,14}}, 
                                      new [,] {{21,22},{23,24},{25,26},{27,28}                                     },
                                     {
                                      new [,] {{31,32},{33,34}}, 
                                      new [,] {{41,42}}},
                                    };

Here we declared a matrix of 2×2. Element at position [0,0] is a matrix of 1×2. Element at position [0,1] is a matrix of 2×2. Element at position [1,0] is a matrix of 1×2 whereas element at position [1,1] is a matrix of 1×1.

Though I will not recommend (as it becomes difficult to maintain and visualize), you can combine jagged arrays with more deeper level to achieve the desired data structure. As an example following code is declaring a matrix where each element is a matrix. Each element of sub matrix is a one dimensional array.

 int[,][,][] conufusing;

.Net and C# release history

I always find it difficult to track .Net and C# language release history. E.g. what .net versions are released with different visual studio versions and what features are available in different versions of C# language. So I thought I will compile this information in this blog so I and other can refer it when needed.

.Net Version Release history
.Net Version Release Date Tool Feature
1.0 2002 Visual Studio .Net First release of .net
1.1 2003 Visual Studio 2003 Support for ASP.Net mobile controls
Supports side-by-side execution
Security Changes
2.0 2005 Visual Studio 2005 Generics (with generic collection)
Nullable Types
Support of IPv6 addresses in .net remoting
Common Language Runtime 2.0
3.0 2006 WCF (Communication framework)
WPF (Presentation framework)
WF (Workflow Foundation)
3.5 2008 Visual Studio 2008 LINQ
Addin / Plugin Model (System.AddIn.Contract.dll)
4.0 2010 Visual Studio 2010 Parallel Computing
Code Contracts
Lazy Initialization
Dynamic Language Runtime
In-process side-by-side hosting
Background garbage collection
Covariance and Contravariance
Common Language Runtime 4.0
4.5 2012 Visual Studio 2012 Enhanced regular expression support
Default culture for application domain
Zip compression
Support of array with size more than 2GB
Asynchronous file operation
Improvement in parallel computing
4.5.1 2013 Visual Studio 2013 Ability to collect diagnostics information
Ability to explicitly compact the large object heap (LOH) during garbage collection
Additional performance improvements such as ASP.NET app suspension
Multi-core JIT improvements


Note:
- .Net 3.5, 3.0 and 2.0 uses same common language runtime version 2.0.
- .Net 4.5, 4.5.1 and 4.0 share same common language runtime version 4.0.
- I have not included language features in above list e.g. Partial classes / anonymous method. I will cover them in following section.

C# Language Release history
C# Version Release Date Tool Feature
1.0 2002 Visual Studio .Net First release of .net
2.0 2005 Visual Studio 2005 Partial classes
Support for generics
Iterators
Nullable syntax
Anonymous methods
Static class
Volatile keyword
3.0 2008 Visual Studio 2008 Implicitly Typed Local Variables
Extension Methods
Lambda Expressions
Type Inference
Object and Collection Initializers
Anonymous Types
Automatically Implemented Properties
Expression Trees
4.0 2010 Visual Studio 2010 Support for Covariance and Contravariance
Optional parameters and named arguments
Support for Dynamic and DLR
Enhanced support for COM interop
5.0 2012 Visual Studio 2012 Async / Await Feature
Support for caller information

Async / Await Threading model.

As part of .Net framework 4.5, Microsoft have extended the language and BCL to support new async and await keywords. These enhancements enable us to provide significant user experience improvements in our apps without much effort. In addition, Microsoft have added a large set of new async APIs within the .NET Framework that can be used along with async / await to develop more responsive UI applications.

I have published an article that provides an understanding of async/await threading model, what problem does it solve and its internal implementation. Here is the link: “Insides Of Async And Await“.

Static constructor and deadlock

Static constructor is used to initialize the static members of a class. As per specification, static constructor is executed at most once in the given application domain and get triggered by
- an instance of the class is created.
- any of the static members of the class are referenced.

The CLR uses an internal lock to ensure that static constructor
- is only called once
- get executed before creation of any instance of the class or before accessing any static members.

With this behaviour of CLR, there is a potential opportunity of a deadlock if we perform any asynchronous blocking operation in static constructor. Here is an example:

class Experiment
{
    public static readonly Experiment Instance;

    static Experiment()
    {
        Instance = new Experiment();
        Console.WriteLine("Initializing the instance on different thread");

        Thread thread = new Thread(() => Instance.Initialize());
        thread.Start();
        thread.Join();
        Console.WriteLine("Initialization completed");
    }

    void Initialize()
    {
        //Initializing members  
    }

    public void SayHello()
    {
        Console.WriteLine("Hello World");
    }
}

 
The main thread will wait for the helper thread to complete within the static constructor. Since the helper thread is accessing the instance method, it will first try to acquire the internal lock. As internal lock is already acquired by the main thread, we will end-up in deadlock situation.

Even if the helper thread is not accessing any instance method, there is a risk that helper thread cause CLR to acquire the internal lock. Here is an example:

class Experiment
{
    static Experiment()
    {
        Thread thread = new Thread(()=>{});
        thread.Start();
        thread.Join();
    }
}

 
An another example with pLinq

class Experiment
{
    public static readonly IEnumerable<int> SquaresOfFirst100Numbers;

    static Experiment()
    {
        Enumerable.Range(1, 100).AsParallel().Select(n => n * n).ToList();
    }
}

 

With this CLR behaviour, we should always avoid having any asynchronous blocking operation in static constructor as it can easily lead to a deadlock situation.

IDisposable interface

One of my friend shared a piece of code from the old legacy codebase. Initially I was quite confident that it will always cause a runtime exception. The code was as follows:

using (myDisposableObject)
{
    //Executing some logic
    myDisposableObject = null;
}

As per my initial understanding, “using” is a compiler feature whereby above code will get compiled as follows:

try
{
  //Executing some logic
  myDisposableObject = null;
}
finally
{
  myDisposableObject.Dispose();
}

With this assumption, it must throw runtime exception for object reference not found.However when I wrote a small test, surprisingly I didn’t get any exception. By looking into the IL, I found that generated code checks for null before calling the Dispose method in finally block. Hence the compiled form is as follows:

try
{
  //Executing some logic
  myDisposableObject = null;
}
finally
{
  if (myDisposableObject != null) myDisposableObject.Dispose();
}

This approach not only fixes the runtime issue but it does provide an additional feature where we can disable disposing of an object within the “using” clause.