I'm trying to make a number of data classes for my C#/XNA game, which would essentially be a wrapper around T[,]:
public interface IGrid<T>
where T : struct
{
Point Size { get; }
T this[int x, int y] { get; set; }
}
For example, I might have a Heightmap object which is essentially an IGrid<float>, or I might have a Level.TileData object which is an IGrid<byte> or IGrid<int>. These could be entirely separate classes with specific helper methods, etc.
I also made a small extension library that operates specifically on any 2-dimensional array:
public static class Transformations
{
static T[,] Transpose(this T[,] value);
static T[,] FlipHorizontal(this T[,] value);
static T[,] FlipVertical(this T[,] value);
static T[,] RotateClockwise(this T[,] value);
static T[,] RotateCounterClockwise(this T[,] value);
}
However, when I actually implement IGrid<T>, I encounter a small design issue.
Because the backing array would be private/protected, any client code that actually uses IGrid<T> would be unable to use my extension library.
According to CA1819 and Eric's blog, publicly exposing an array (even via properties!) is a bad idea, as it would be fully mutable. The suggested workaround is to clone the array, then expose it as an immutable type (which means I still don't have an array to use the library on).
Am I overthinking things, or is there an elegant solution here? I really like the idea of using indexers to read/write data on the object, but in some situations I might want to work with the entire array at once.