Interface for a transformable grid I am working on an XNA project, and since procedural generation is likely to be used, I wanted to eventually create a helper class to work with data to facilitate that.

Design Goal:

Originally, I wanted to generate and modify a heightmap in a simple but efficient manner. The most straightforward approach to handle this would be a with a float[,].

Right now, I have a Grid&lt;T&gt; which simply holds the data in a more convenient manner, but I want to introduce a way to transform it somehow - slicing, rotations, etc. The ability to add and multiply different heightmaps together would be beneficial as well.

My Code:

Knowing that C# is optimized for single-dimensional arrays, I decided to make a simple wrapper class that contains an internal jagged array, but have it look and behave like a 2-dimensional array.

I first made it into an interface because doing so allows me to implement it however I want, which allows for future optimizations which won't break any dependent code:

// Presents itself as a simplified 2-dimensional array
public interface IGrid&lt;T&gt; : IEnumerable&lt;T&gt;, IEnumerable
{
    Point Size { get; }
    T this[int x, int y] { get; set; }
}


And the current (simplified) implementation is:

// Functions as a jagged array under the hood
public class Grid&lt;T&gt; : IGrid&lt;T&gt;
{
    private readonly T[][] _values;

    // Implement IGrid&lt;T&gt;
    public Point Size { get; private set; }
    public T this[int x, int y]
    {
        get { return _values[y][x]; }
        set { _values[y][x] = value; }
    }

    // Constructor
    public Grid(int x, int y)
    {
        Size = new Point(x, y);
        _values = new T[y][];
        for (int i = 0; i &lt; y; i++)
            _values[i] = new T[x];
    }

    // Provide IEnumerator, override ToString(), etc...
}


My approach for the transformation bits is similar:

public interface ITransformable&lt;T&gt;
{
    T Slice(int x, int y, int width, int height);
    T Slice(Rectangle value);
    T Transpose();
    T Flip(bool horizontal, bool vertical);
    T Rotate(bool clockwise);
}


And here is where I am stumbling. I'm not actually sure what I want to do with it!


Attach it to IGrid&lt;T&gt;. It's no longer about simply storing the data, but transforming it as well.
Attach it to Grid&lt;T&gt;. The fact that a grid can transform the data is an implementation detail.
Create a derived class Mesh&lt;T&gt; which does everything Grid&lt;T&gt; does, but also implements ITransformable&lt;T&gt;.
Create a derived class Mesh&lt;T&gt;, but remove ITransformable&lt;T&gt; and move its methods into this class.


Thoughts:

Since generic types do not support operator overloading (+, -, /, *), it means that if I want a Heightmap to support addition in the form of Heightmap m = a + b, it would need a specific implementation, such as public class Heightmap : Mesh&lt;float&gt;, which then supplies the implementation of the operators.

Based on that, my entire class chain might resemeble:

public interface IGrid&lt;T&gt; { ... }
public interface IMesh&lt;T&gt; : IGrid&lt;T&gt; { ... }
public class Grid&lt;T&gt; : IGrid&lt;T&gt; { ... }
public class Mesh&lt;T&gt; : Grid&lt;T&gt;, IMesh&lt;T&gt; { ... }
public class Heightmap : Mesh&lt;float&gt; { ... }
I think you should use aggregation.

It's either:

class Mesh&lt;T&gt; : ITransformable&lt;T&gt;
{
    public Mesh(IGrid&lt;T&gt; grid, ....)
    {
        Grid = grid;
        ......
    }

    public IGrid&lt;T&gt; Grid { get; private set; }
    .....
}


or:

class Transformer&lt;T&gt; : ITransformer&lt;T&gt;
{
    public T Slice(IGrid&lt;T&gt;, int x, int y, int width, int height)
    {
        ...
    }
    ....
}


It's hard to tell which is better without good understanding of your design (which I don't have). But generally I would prefer the second option.

Also, your IGrid implementation looks really weird. You are saying that you want to implement 2D array using 1D array, yet you use T[][] _values; in your implementation. So, what's the point? There is also a System.Windows.Size class, so I don't understand why would you want to use a Point.