I am trying to adapt the following code, to also acceptable nullable type. Consider this:
public sealed class JsonDictionary
{
private readonly IDictionary<string, object> _data;
public static readonly Key<int> Foo = new Key<int> { Name = "FOO" };
public static readonly Key<double> Bar = new Key<double> { Name = "BAR" };
public static readonly Key<List<double>> Vec = new Key<List<double>> { Name = "VEC" };
public JsonDictionary()
{
_data = new Dictionary<string, object>();
}
public void Set<T>(Key<T> key, T obj)
{
_data[key.Name] = obj;
}
public T Get<T>(Key<T> key)
{
return (T)_data[key.Name];
}
public class Key<T>
{
public string Name { get; init; }
}
}
This works quite well:
var d = new JsonDictionary();
d.Set(JsonDictionary.Foo, 42);
d.Set(JsonDictionary.Bar, 3.14);
d.Set(JsonDictionary.Vec, new List<double> { 1.0, 2.0, 3.0 });
Assert.Equal(42, d.Get(JsonDictionary.Foo));
Assert.Equal(3.14, d.Get(JsonDictionary.Bar));
Assert.Equal(new List<double> { 1.0, 2.0, 3.0 }, d.Get(JsonDictionary.Vec));
How can I change the Set/Get API to also accept nullable type ? For instance:
d.Set(JsonDictionary.Foo, null);
d.Set(JsonDictionary.Bar, null);
d.Set(JsonDictionary.Vec, null);
The following naive attempt did not work for me:
public void Set<T>(Key<T> key, T? obj)
{
_data[key.Name] = obj;
}
Changing the base type as in:
public static readonly Key<int?> Foo = new Key<int?> { Name = "FOO" };
public static readonly Key<double?> Bar = new Key<double?> { Name = "BAR" };
public static readonly Key<List<double>?> Vec = new Key<List<double>?> { Name = "VEC" };
does work as expected, but requires a bit more typing ... any other solution directly at the Set
function (with some constraints magic) ?
Another solution could be duplicating the code like this:
public void Set<T>(Key<T> key, T? obj) where T : struct
{
_data[key.Name] = obj;
}
public void Set<T>(Key<T> key, T? obj) where T : class
{
_data[key.Name] = obj;
}
which is also something I do not wish to do. Am I missing something fundamental in this strongly-typed structure ?