Ever since the .NET source code has been available, I roam through it now and then to learn some things.

I'm assuming the people who create .NET Framework and .NET Core are experts at .NET.

I think it could be interesting to pick some random source code from there and discuss things that look interesting.

I'm going to assume some experience programming with .NET / C#.

Where are the sources?

You can find the .NET Core source code on github.

You can find the .NET Framework source code on the Reference Source pages.

System.Json.JsonObject

To get our feet wet, let's have a look at some lines in System.Json.JsonObject.

Using alias directive

On line 9 and 10 we see:

using JsonPair = System.Collections.Generic.KeyValuePair<string, System.Json.JsonValue>;
using JsonPairEnumerable = System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<string, System.Json.JsonValue>>;

If you have done any .NET, you will already be familiar with the Using directive. Mostly used as follows:

using System.IO;
using System.Text;

This makes the classes from those namespaces available in your code, without you having to prefix them with their namespaces. So you can write File.Open instead of System.IO.File.Open.

What is used for JsonPair and JsonPairEnumerable is a using alias directive.

After declaring the alias, you can write JsonPair instead of System.Collections.Generic.KeyValuePair<string, System.Json.JsonValue>. Shorter and easier to read.

In other words, the following two lines of code are identical:

var pair1 = new JsonPair();
var pair2 = new System.Collections.Generic.KeyValuePair<string, System.Json.JsonValue>();

This can also be useful if you have two namespaces that have a class with the same name, and you want to be able to tell them apart.

Note that this alias only applies to that source file. You can't just use JsonPair in other files. That's why the alias is declared again in System.Json.JsonValue.

With the using alias directive you can make the code easier to read by providing classes shorter names, or solve class name ambiguity.

SortedDictionary

The next thing that caught my eye was the use of a SortedDictionary on line 17:

// Use SortedDictionary to make result of ToString() deterministic
private readonly SortedDictionary<string, JsonValue> _map;

Luckily, the comment immediatly explains why they chose this type.

For those unfamiliar with a Dictionary: it's a list of key-value pairs. You can look up a value using the key: var value = myDictionary["key"]. This structure is better known as a HashTable.

The base class of JsonObject is JsonValue. This base class has a ToString method that calls the Save method on JsonObject. The Save method writes the json object to a stream.

In the Save method you can see a loop through the SortedDictionary:

public override void Save(Stream stream)
{
    // code ommited ...
    
    foreach (JsonPair pair in _map)
    {
        // code ommited ...
    }
}

In the SortedDictionary, this foreach will run through all items sorted by the Key value. In a regular Dictionary you do not really know in what order you will get the items.

params

Directly under the SortedDictionary, in the constructor of JsonObject there's usage of the params keyword. On line 19:

public JsonObject(params JsonPair[] items)
{
    _map = new SortedDictionary<string, JsonValue>(StringComparer.Ordinal);

    if (items != null)
    {
        AddRange(items);
    }
}

We see the constructor accepts an array of JsonPair objects. The params keyword indicates you can pass the list of all items for this array as individual arguments into the function.

The following code:

var jsonObject = new JsonObject(new JsonPair(), new JsonPair(), new JsonPair())

will result in a call to the constructor with "items" being an array of three JsonPair's.

You are perhaps already familiar with this through Console.WriteLine.

Which has the following signature:

public static void WriteLine(String format, params Object[] arg)

and which is called as follows:

Console.WriteLine("Hello, {0}! My name is {1}.", "World", "Aaron");

So the arg array will contain the two strings passed: "World" and "Aaron".

Much like the alias, the params keyword is a way to make your code easier to read. In this case code where you call a method that accepts an array of objects as a parameter.

Summary

I only went to line 19 of a single file, but already spotted three things I do not use every day:

When browsing through the code, I think it's interesting to note things that are less common and figure out what they are being used for. And if they look unfamiliar, to read up on those features.

I'll be digging into other files in future posts.

Have you learned from having this code available? Made any interesting finds? Feel free to leave a comment.