I can see two concerns in this question
How to create an array with non-default prefilled values?
There is no clean way to fill a generic array with custom default value, except for creating it manually.
You might want to read this StackOverflow question too, because it is related to this topic:
What is the equivalent of memset in C#?
Taking this into account, you can define your Grid
class as the following:
public class Grid<T>
{
private T[] _gridArray;
public Grid(int size)
{
_gridArray = new T[size];
}
public Grid(int size, T initialValue)
{
_gridArray = new T[size];
for (int i = 0; i < size; i++)
_gridArray[i] = initialValue;
// or it can be rewritten with LINQ, if you like:
// _gridArray = Enumerable.Repeat(initialValue, size).ToArray();
}
}
Now, you can use it to create default arrays:
var grid = new Grid<int>(3); // [0, 0, 0]
var grid = new Grid<object>(3); // [null, null, null]
var grid = new Grid<bool>(4); // [false, false, false, false]
but you can also provide a value which you would like to be as a default:
var grid = new Grid<int>(3, -1); // [-1, -1, -1]
var grid = new Grid<bool>(4, true); // [true, true, true, true]
How to set custom default values per generic T
If you want -1
to be default value for all Grid<int>
, you can create a factory, which will know about it and create this according to this logic. This factory can store default values for each type and validate your T
against them.
Of course, you could put this logic into constructor just like you initially wanted it to be:
public class Grid<T>
{
private static readonly Dictionary<Type, object> _customDefaultValues = new Dictionary<Type, object>
{
[typeof(int)] = -1,
[typeof(long)] = long.MaxValue
};
public T[] _gridArray;
public Grid(int size)
{
_gridArray = new T[size];
if (_customDefaultValues.TryGetValue(typeof(T), out object defaultValue))
{
T defaultValueUnboxed = (T)defaultValue;
for (int i = 0; i < size; i++)
_gridArray[i] = defaultValueUnboxed;
}
}
}
var grid = new Grid<int>(4); // [-1, -1, -1, -1]
var grid = new Grid<long>(2); // [long.MaxValue, long.MaxValue]
var grid = new Grid<bool>(3); // [false, false, false]
but for me it looks a little bit sloppy and non-transparent. Also, it creates new instance of static _customDefaultValues
for each create closed generic type. That's why it would be better to extract it to a factory class.
public class Grid<T>
{
private T[] _gridArray;
public Grid(int size)
{
_gridArray = new T[size];
}
public Grid(int size, T initialValue)
{
_gridArray = new T[size];
for (int i = 0; i < size; i++)
_gridArray[i] = initialValue;
}
}
public static class GridFactory
{
private static readonly Dictionary<Type, object> _customDefaultValues = new Dictionary<Type, object>
{
[typeof(int)] = -1,
[typeof(long)] = long.MaxValue
};
public static Grid<T> Create<T>(int size)
{
if (_customDefaultValues.TryGetValue(typeof(T), out object defaultValue))
return new Grid<T>(size, (T)defaultValue);
return new Grid<T>(size);
}
}
It results into more code, but this way it looks more clear:
var grid = GridFactory.Create<int>(3); // [-1, -1, -1]
var grid = GridFactory.Create<long>(4); // [long.MaxValue, long.MaxValue, long.MaxValue, long.MaxValue]
var grid = GridFactory.Create<object>(3); // [null, null, null] by default