Serializing/Deserializing Dictionaries with Tuple as Key

Sometimes you run into things that might look trivial but it just do not work as expected. One such example is when you attempt to serialize/Deserialize a Dictionary with Tuples as the key. For example

var dictionary = new Dictionary<(string, string), int>
{
[("firstName1", "lastName1")] = 5,
[("firstName2", "lastName2")] = 5
};

var json = JsonConvert.SerializeObject(dictionary);
var result = JsonConvert.DeserializeObject<Dictionary<(string, string), string>>(json);

The above code would trow an JsonSerializationException when deserializing. But the good part is, the exception tells you exactly what needs to be done. You need to use an TypeConverter here.

Let’s define our required TypeConverter

public class TupleConverter<T1, T2> : TypeConverter
{
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
return sourceType == typeof(string) || base.CanConvertFrom(context, sourceType);
}

public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
var elements = Convert.ToString(value).Trim('(').Trim(')').Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
return (elements.First(), elements.Last());
}
}

And now, you can alter the above code as

TypeDescriptor.AddAttributes(typeof((string, string)), new TypeConverterAttribute(typeof(TupleConverter<string, string>)));
var json = JsonConvert.SerializeObject(dictionary);
var result = JsonConvert.DeserializeObject<Dictionary<(string, string), string>>(json);

With the magic portion of TypeConverter in place, your code would now work fine. Happy Coding.

Evil Code #010 : Extension Methods

Back with Evil Code Series again. What would be the output of the following.

void Main()
{
PrintToString("SampleText");
PrintToDescription("SampleText");
PrintToString(null);
PrintToDescription(null);
}
public void PrintToString(string valueToPrint)
{
Console.WriteLine($"Printing From {nameof(PrintToString)} : {valueToPrint.ToString()}");
}

public void PrintToDescription(string valueToPrint)
{
Console.WriteLine($"Printing From {nameof(PrintToDescription)} : {valueToPrint.ToDescription()}");
}

public static class Extensions
{
public static string ToDescription(this string source)
{
return $"Description = {source??"Null"}";
}
}

The code attempts to prints 2 set of data, “SampleText” and Null Value. The PrintToString method, prints the output from the inbuild ToString() method, while the second method PrintToDescription, prints the output from an extension method.

The extension method, as such, doesn’t do anything fancy. It merely adds a prefix to the string (if not null or prints null).

It would be natural to expect the firs two method calls to print normally and then the last two calls, with null as paramter, to throw exceptions. But this is where things to change and expose the functioning of Extension methods.

While the extension methods work quite similiar to instance method, there is one fundamental difference. It has ability to execute even if the source instance if null.

In our given code, in the final call to PrintToDescription, even with a null paramter, the extension method is invoked, while the PrintToString would throw an exception as soon as null.ToString is encountered.

The output of the above code would be as following.

1. Printing From PrintToString : SampleText
2. Printing From PrintToDescription : Description = SampleText
3. // Throws Exception
4. Printing From PrintToDescription : Description = Null