As documented upstream, one cannot use 'array' as base constraints:
[...]Some types are disallowed as a base class constraint: Object, Array, and ValueType.[...]
However there seems to be minimal type inference for array as seen at:
My goal is to extend the original SO post, to handle also array types:
So my naive attempt is as follow:
public class JsonDictionary
{
public static readonly Key<int> Int = new Key<int> { Name = "INT" };
public static readonly Key<int[]> Int3 = new Key<int[]> { Name = "INT3" };
IDictionary<string, object> _data;
public JsonDictionary()
{
_data = new Dictionary<string, object>();
}
public void Set<T>(Key<T> key, T obj)
{
if (obj is int[] objArray) // FIXME: runtime check
{
if (objArray.Length != 3)
throw new FormatException("Illegal INT3");
}
_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; }
}
}
Usage is simply:
var d = new JsonDictionary();
d.Set(JsonDictionary.Int, 42);
var i = d.Get(JsonDictionary.Int);
d.Set(JsonDictionary.Int3, new int[] { 1, 2, 3 });
var i3 = d.Get(JsonDictionary.Int3);
Assert.Throws<FormatException>(() => d.Set(JsonDictionary.Int3, new int[] { 1, 2 }));
Notice how I used a runtime check (obj is int[] objArray
) because I could not use some kind of constraint for 'array'.
Is there a way to rewrite the above so that I can have two different Set
functions, one for T
and one for T[]
. Otherwise I would need to handle all possible types with an ugly if/else:
if (obj is int[] objArray)
{
if (objArray.Length != 3)
throw new FormatException("Illegal INT3");
}
else if (obj is ushort[] objArray)
{
if (objArray.Length != 3)
throw new FormatException("Illegal USHORT3");
}
else if (obj is double[] objArray)
{
if (objArray.Length != 3)
throw new FormatException("Illegal DOUBLE3");
}
[...]