Sto provando a creare un certo numero di classi di dati per il mio gioco C # / XNA, che sarebbe essenzialmente un wrapper attorno a T[,]
:
public interface IGrid<T>
where T : struct
{
Point Size { get; }
T this[int x, int y] { get; set; }
}
Ad esempio, potrei avere un oggetto Heightmap che è essenzialmente un IGrid<float>
, oppure potrei avere un oggetto Level.TileData che è un IGrid<byte>
o IGrid<int>
. Queste potrebbero essere classi completamente separate con specifici metodi di supporto, ecc.
Ho realizzato anche una piccola libreria di estensioni che opera specificamente su qualsiasi array bidimensionale:
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);
}
Tuttavia, quando implemento effettivamente IGrid<T>
, ho riscontrato un piccolo problema di progettazione.
Poiché l'array di backup dovrebbe essere privato / protetto, qualsiasi codice client che effettivamente utilizza IGrid<T>
non sarebbe in grado di utilizzare la mia libreria di estensioni.
In base a CA1819 e blog di Eric's , esponendo pubblicamente un array (anche tramite le proprietà!) è una cattiva idea, in quanto sarebbe completamente modificabile. La soluzione suggerita è quella di clonare l'array, quindi esporlo come un tipo immutabile (il che significa che non ho ancora una matrice su cui utilizzare la libreria).
Sto pensando troppo a qualcosa, o c'è una soluzione elegante qui? Mi piace molto l'idea di usare gli indicizzatori per leggere / scrivere i dati sull'oggetto, ma in alcune situazioni I potrebbe voler lavorare con l'intero array in una sola volta.