Inline Initialization

I must admit that I was rather surprised when I learnt that inline initialization translates into the default constructor-based initialization in the IL. So, for example, these two pieces of code are equivalent:

    sealed internal class Inline
    {
        private int x = 5;
    }


is the same as

    sealed internal class Inline
    {
        public Inline()
        {
            x = 5;
        }

        private int x;
    }

The above can be verified by examining the IL of the first example through the ILDASM. Below I am showing the snapshot of what the IL code in .ctor generated by the IL looks like:

InLineIL

As pointed out in ([1], chapter 8), this means that non-constant fields initialized inline lead to the IL code explosion.

In one of my previous posts on C# language features I wrote that parameter-less constructors are not allowed in value types before C# 6.0. This is the reason why inline initialization is illegal in structs. For example, the following won’t compile:

    struct NoInline
    {
        int a = 5;
    }

If you examine the IL for the struct, you will see that it has no code for the default .ctor. The implicit parameter-less constructor is intrinsic to the struct (i.e. it is provided by the C# language implementation) and cannot be modified. Thus, for C# struct, there is no way to translate the inline initializers into the initialization inside the parameter-less constructor.

The story is very different for static fields. In value types, static fields can be initialized inline. As you may have already guessed, such initialization does translate into the parameter-less static constructor initialization. For example, these two pieces of code are equivalent in the IL:

struct NoInline
{
        static int a = 5;
}

is the same as

struct NoInline
{
    static NoInline()
    {
        a = 5;
    }

        static int a;
}

References:
[1] J.Richter. CLR via C#, 4th edition. 2014.

Not So Readonly

Greetings to all my blog readers!

In C# the readonly keyword can be very handy. It allows one to define fields that are assigned at the point of instance creation (in the instance constructor), or inline, at the point of declaration. Once assigned, the fields remain immutable and cannot be reassigned by the type consumers. Of course, another type instance can be created, and it may have different values assigned to its readonly fields (e.g. if the constructor uses input parameters to perform the assignment).

Unlike constants, readonly fields are initialized at run time. This can be useful to avoid the application assembly versioning problem that may arise from using constants. Great! Let’s go ahead and create some readonly arrays!

In the below code I create an int array myIntArray, which is marked with readonly keyword and assigned in the constructor of IntArray class. In the Main method I am subsequently modifying the first value in the array and print it out to show that it has changed. The code compiles and prints out 6, 2, 3, 4 and 5. But wait! Didn’t I just say that readonly fields cannot be modified by the type consumers? What is going on here?

using System;
using System.Linq;

namespace ReadOnlyRef
{
    sealed internal class IntArray
    {
        internal IntArray()
        {
            myIntArray[0]=  1;
            myIntArray[1] = 2;
            myIntArray[2] = 3;
            myIntArray[3] = 4;
            myIntArray[4] = 5;
        }

        internal readonly int [] myIntArray= new int[5]; 
    }

    class EntryPoint
    {
        static void Main(string[] args)
        {
            IntArray ia = new IntArray();
            ia.myIntArray[0] = 6;

            for (int i = 0; i < ia.myIntArray.Count(); i++)
                Console.WriteLine(ia.myIntArray[i].ToString());
            
            Console.ReadLine();
        }
    }
}  

Well, in the above code we got exactly what we were asking for – the int array is readonly, that is, its reference is readonly. So, if we declare another instance of IntArray and attempt the following reassignment, it won’t work:

IntArray ia2 = new IntArray();
ia2.myIntArray = ia.myIntArray;

The above won’t compile and the error is: ‘A readonly field cannot be assigned to (except in a constructor or a variable initializer).’

When the readonly field is a reference type, it is its reference and not the object that becomes readonly. To make the object readonly, I can suggest doing one of the following two:

1. The easiest and the most elegant way is to make the readonly field private, assign it once in the constructor, and make it accessible via the readonly property:

internal IntArray()
{
    myIntArray[0]= 1;
    myIntArray[1] = 2;
    myIntArray[2] = 3;
    myIntArray[3] = 4;
    myIntArray[4] = 5;
}

internal int[] MyIntArray
{
  get { return myIntArray; }
}

private readonly int [] myIntArray= new int[5];



… in the type consumer…

IntArray ia = new IntArray();
int[] arrayCopy = ia.MyIntArray;

for (int i = 0; i < arrayCopy.Count(); i++)
     Console.WriteLine(arrayCopy[i].ToString());

2. You can achieve reference field immutability through implementing readonly interfaces. Check out this post if you want to know more. With this design, the type consumer would need to make a conscious choice to ensure immutability.

Silent Boxing

Here is an innocent piece of code for you. Can you spot if there is anything wrong with it?

using System;

namespace SilentBoxing
{
    class EntryPoint
    {
        static void Main(string[] args)
        {
            double d = 25.5;
            Console.WriteLine("You set d to be {0}", d);
            Console.WriteLine("If you add 5 to d, it will become " + (d + 5));
            Console.ReadLine();
        }
    }
}

It compiles and runs as expected, however, there is something wrong with it. As you may have guessed from the title of this blog post, this code requires boxing. Times two. The boxing occurs in the calls to Console.WriteLine. First time we call WriteLine, the compiler resolves the call to

Console.WriteLine (String, Object[])

Note that the array of parameters is of type Object. Thus the double d is boxed into an object.

The second type boxing occurs is in the second call to WriteLine, which is resolved with the following overload:

Console.WriteLine (String)

Since we are creating the string on the fly, the (d+5) expression is boxed into an object and concatenated with the string.

Boxing of value types is something to watch out for. It is undesirable because it pollutes the managed heap. A boxed value type requires allocating memory on the managed heap to contain the value and its type, since objects on the heap get allocated a type object containing, among other things, the type object pointer and the sync block index. The type object pointer is what allows two or more reference types to point to the same object. The sync block index is used to synchronise access to a reference type from difference threads. None of this great functionality is required within our WriteLine calls.

So, how can we eliminate the need for boxing? Below is the code without it, and it is done with the use of ToString() method. System.Double.ToString overrides ToString() from System.ValueType parent. It returns a string and does not cause boxing. Note that calling ToString() on most build-in types does not cause boxing. If you write your own struct, consider overriding ToString() to avoid potential performance downgrade.

// ...
Console.WriteLine("You set d to be {0}", d.ToString());                       // No more boxing!
Console.WriteLine("If you add 5 to d, it will become " + (d + 5).ToString()); // No more boxing!
// ...

Dynamic Cast with Generic Collection

Greetings to my blog readers!

In this post I will share with you a trick of achieving something that, quite frankly, I do not recommend doing – dynamically casting types in generic collections.
In my previous post here I showed you that generic custom collections are great, type-safe and can be easily created by deriving from System.Collections.ObjectModel.Collection which provides a wealth of ready-made functionality. So, suppose you have a need for a custom generic collection like this, but you need to be able to treat it as a polymorphic type. For example, if you create a collection of integers, you want to be able to convert it to a collection of doubles when there is a need to do so. Or the other way around.

To begin with, you may try doing something like this, where NumericalList class is initialised with an int type, but then attempting to cast to a list of doubles to save into doubleList:

using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;


namespace TypeSafety
{
    sealed class NumericalList<T> : System.Collections.ObjectModel.Collection<T>
    {
        
    }
    
    class EntryPoint
    {
        static void Main(string[] args)
        {
            NumericalList<int> intList = new NumericalList<int> {1,2,3,4,5};

            var doubleList = from double n in intList select n;
            
            foreach (var d in doubleList)
                Console.WriteLine(d);

            Console.ReadLine();
        }

    }
}

The above code will compile, but it will not run. The reason for this is not very intuitive because one should be able to cast an int to a double implicitly. The runtime exception is System.InvalidCastException, originating from the line where doubleList is initialised and later unwound in the foreach block. So, what is going on here?

Examining the IL for the above code we can find this statement corresponding to the instructions where we attempt the implicit cast: System.Linq.Enumerable::Cast(class[mscorlib]System.Collection.IEnumerable)
The Enumerable.Cast is called by the foreach iterator, and the cast fails with the exception. The method Cast is an extension to Enumerable class. You can examine the source code for the whole class here. Below I am providing the snippets of code from the referencesource.microsoft.com that are relevant to our problem:

public static IEnumerable<TResult> Cast<TResult>(this IEnumerable source) {
            IEnumerable<TResult> typedSource = source as IEnumerable<TResult>;
            if (typedSource != null) return typedSource;
            if (source == null) throw Error.ArgumentNull("source");
            return CastIterator<TResult>(source);
        }
 
        static IEnumerable<TResult> CastIterator<TResult>(IEnumerable source) {
            foreach (object obj in source) yield return (TResult)obj;
        }

Since as never throws an exception, the exception is thrown from the CastIterator extension where the cast takes place. The explicit cast is from object to, in our case, double, which is invalid.

Ok, now that we know where and why the code fails, let’s look at how we can fix it. A simple fix is to move the cast to where it will work, i.e. to where the selected list element (an integer) can be cast to a double one at a time:

var doubleList = from n in intList select (double)n;

This does the job. But not at a class level. To be able to perform the kind of conversion we tried originally, we need to modify the default Cast extension. In particular, we need to remove the ‘casting object to a double’ part. To do this, we can utilise the dynamic keyword, which allows us to determine the type at runtime. I am not going to go into the details about this keyword here. Take a look at this comprehensive article on MSDN magazine if you are interested to learn more about dynamic. Below is the modified solution adapted for integers and doubles:

using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;

namespace TypeSafety
{
    sealed class NumericalList<T> : System.Collections.ObjectModel.Collection<T>
    {
        public IEnumerable<TRes>CustomCast<TRes>()
        {
            if (typeof(TRes).Equals(typeof(double)) || typeof(TRes).Equals(typeof(int)))
            {
                dynamic runtime;
                foreach (var tr in this)
                {
                    runtime = tr;
                    yield return (TRes)runtime;
                }
            }
        }
    }
    
    class EntryPoint
    {
        static void Main(string[] args)
        {
            NumericalList<int> intList = new NumericalList<int> {1,2,3,4,5 };
            
            var doubleList = from double n in intList.CustomCast<double>() select n;

            foreach (var d in doubleList)
                Console.WriteLine(d);

            Console.ReadLine();
        }

    }
}


The above works for doubles and integers.

C# Language Features

This blog post is about some features of C# language. Sometimes, as I am thinking about a certain language feature, I ask myself why something is the way it is. Some questions find immediate answers. Mind you, the questions are almost always rather obscure and perplexing. For example, it is immediately clear why interfaces cannot contain other interfaces. It’s because a nested interface implementation is not different from a non-nested one. However, for other questions I don’t have immediate answers and have to spend some time thinking. Take a look and see how many of them you can answer easily. I am providing my answers right below.

  1. Why is it only possible to have one static constructor in a class?
  2. Why is it not possible to declare a class or a struct inside a method?
  3. Classes can be nested. Can methods contain methods? Can methods contain delegates?
  4. Why static constructors can only operate on static fields?
  5. Do structs receive default parameterless constructors if no constructor is provided in the struct definition?
  6. It is possible to have checked{} and unchecked{} regions of code. What is the default behavior?
  7. Why is it not possible to specify an access specifier on a static constructor? What is the provided access on static constructors?
  8. Instance constructors are not inherited. Are static constructors inherited?
  9. Will a class that has only a static constructor receive a default instance constructor?
  10. What is the output of the following piece of code:

using System;
using System.Collections.Generic;

namespace TestingStatic
{
    class Test
    {
        public Test()
        {
            t = 3;
            Console.WriteLine("Inside instance constructor");
        }

        static Test()
        {
            t = 4;
            Console.WriteLine("Inside static constructor");
        }

        public static int t;
    }
   
    class EntryPoint
    {
        static void Main(string[] args)
        {
            Test thisTest = new Test();
            Console.WriteLine(Test.t);
            Console.ReadLine();
        }
    }
}

Why is it only possible to have one static constructor in a class?

A static constructor is invoked when a class is used for the first time. If there were two or more static constructors, then the runtime would somehow need to know which one it should call. A static constructor cannot have input or output parameters, thus purely syntactically two static constructors in a class definition would have identical signatures. This makes it impossible to define more than one static constructor, but makes it very clear for the runtime which one should be invoked.

Why is it not possible to declare a class or a struct inside a method?

This questions can be answered in several ways. My favorite answer stems from the language design and type hierarchy. If you have a better answer – please let me know.
So, C# constructs can be broken into types and members. The types are: classes, structs, interfaces, delegates and enums. The members are fields, methods, indexers, properties, events, operators, constructors and destructors. Are you thinking that an int is also a type? Yes, it is, but it is a primitive type which, under the above hierarchy, is simply a field. The main design idea is that types contain members that perform some operations. Here ‘contains’ means defines and operates on.
A certain inner hierarchy exists within the types. At the top we have classes and structs that can contain all members and some other types including other classes and structs. It would not make sense for a class to contain interfaces, because this would mean they still need to implement them as well. So, we could say a class ‘contains’ an interface when it implements it. Interfaces follow classes in the sub-hierarchy. Interfaces can contain some members only, like methods, properties, events and indexers. Then come enums that can only contain named constants. Delegates are the last in this sub-hierarchy: they cannot contain any types or members, but they are still types.
Members cannot contain types. Members cannot contain other members, except for fields. For example, a method can declare its own local fields of primitive type, like int, object or string. Constructors, destructors and events are forms of methods. Properties are extensions of fields, and they are also methods. Methods cannot contain other methods. Events are fields, but of delegate type.

Classes can be nested. Can methods be nested? Can methods contain delegates?

Just like the answer to the second question above, no, methods cannot contain other methods. Methods cannot define delegates, because members cannot contain/define named types.

Why static constructors can operate only on static fields?

This has to do with the order in which static and instance fields and constructors are allocated in the memory and initialised. When a class contains static fields and/or static constructor, the order of field initialisation is the following. The static field initializers execute before the static constructor. Thus, when these fields are referenced in the body of a static constructor, which happens next, they are already initialised. At the point of static constructor invocation, no instance fields have been yet initialised by the CLR. This happens next, and it is followed by the instance constructors. So, static constructors can only operate on static fields, because non-static fields are not guaranteed to have been properly type initialised by the CLR at the point of execution.

Do structs receive default parameterless constructors if no constructor is provided in the struct definition?

The answer is yes, because all value types receive an implicit parameterless constructor. This makes it possible to declare structs and other value types using new keyword. Also, because a parameterless constructor is provided, no parameterless constructor can be defined/overloaded in the struct (Note: true for C# up to C# 6.0!). However, structs can define own constructors with parameters. Note that, unlike with classes, this implicit parameterless constructor is not visible in ILDASM.

It is possible to have checked{} and unchecked{} regions of code. What is the default behavior?

The default, if one can call it default, is unchecked. However, this is only if the compiler is invoked without the ‘\checked’ or ‘\unchecked’ options. Some people become surprised when they realise that overflow occurs silently in the unchecked region of code. However, before you decide to use ‘checked’ from now on, consider the impact on performance.

Why is it not possible to specify an access modifier on a static constructor? What is the provided access on static constructors?

Static constructors are always private. It is not possible to override this access modifier, thus it is not possible to specify an access modifier on a static constructor.

Instance constructors are not inherited. Are static constructors inherited?

No they are not inherited. No constructors or destructors are inherited.

Will a class that has only a static constructor receive a default instance constructor?

The answer is yes, it will receive a default parameterless constructor. This is because it still should be possible to create instances of such class with the new keyword. Note that this is true for non-static classes only. Static classes do not receive a default parameterless constructor.

What is the output of this code?

The output is given below. You should be able to understand why this is the output if you understand the answer to question 4:

Inside static constructor
Inside instance constructor
3

I hope at least some of you found this useful. Let me know if you think any of my answers can be improved upon!