2009-09-03 5 views
1

Je suis sacrément nouveau à C# et je n'arrive pas à comprendre comment exprimer quelque chose de très simple.C# Arrays & Properties

J'ai un tableau 3D privé.

je n'ai aucun problème avec la fonction qui expose le contenu à lire:

public Terrain Tile(int x, int y, int z) { return .... 

mais je veux aussi une fonction interne qui fournit un accès en lecture/écriture avec une transformation de coordonnées.

Il ne semble pas possible de spécifier un paramètre. En regardant le site de Microsoft, il semble qu'il veut [] au lieu de (), mais cela amène le compilateur à penser qu'il s'agit d'une définition de tableau et bien sûr, il barfs partout. Googling ailleurs je trouve beaucoup de gens essayant de modifier un champ de quelque chose retournant un type de référence qui échoue bien sûr mais ce tableau est plein d'énumérations, pas de types de référence.

Bien sûr, je peux écrire une fonction SetTile(x, y, z, terrain) mais être en mesure d'y accéder en tant que tableau est tellement plus clair & élégant, mais il semble être impossible.

+1

Voulez-vous dire que vous souhaitez mettre en œuvre un indexeur pour votre classe? –

Répondre

4

Vous pouvez définir une classe « vue » avec un indexer qui est essentiellement une propriété avec des arguments:

private Terrain[,,] rawArray = ...; 
private View transformedArray = new View(rawArray); 

private class View 
{ 
    private Terrain[,,] array; 

    public View(Terrain[,,] array) 
    { 
     this.array = array; 
    } 

    public Terrain this[int x, int y, int z] 
    { 
     get { ... } 
     set 
     { 
      this.array[2*x, 3*z, -y] = value; 
     } 
    } 
} 
+0

Même problème qu'avec la réponse de Silky - Je veux à la fois la vue brute et la vue transformée. –

+0

Hey dtb, puis-je avoir une opinion sur ma classe? –

+0

Je suis d'accord que les indexeurs sont ce que je veux (pourquoi le terme séparé ??) mais je ne suis pas ce que vous faites ici. Cela fournit le tableau transformé mais je ne vois pas comment il fait aussi le brut. –

0

Pour étendre sur la réponse de DTB, je l'ai écrit la classe transformation suivante:

public class Transform<T, K> 
{ 
    Func<K, T> _getFunc1; 
    Func<K, K, T> _getFunc2; 
    Func<K, K, K, T> _getFunc3; 
    Action<K, T> _setFunc1; 
    Action<K, K, T> _setFunc2; 
    Action<K, K, K, T> _setFunc3; 
    public T this[K k1] 
    { 
     get 
     { 
      if (_getFunc1 == null) throw new ArgumentException(); 
      return _getFunc1(k1); 
     } 
     set 
     { 
      if (_getFunc1 == null) throw new ArgumentException(); 
      _setFunc1(k1, value); 
     } 
    } 

    public T this[K k1, K k2] 
    { 
     get 
     { 
      if (_getFunc2 == null) throw new ArgumentException(); 
      return _getFunc2(k1, k2); 
     } 
     set 
     { 
      if (_getFunc2 == null) throw new ArgumentException(); 
      _setFunc2(k1, k2, value); 
     } 
    } 

    public T this[K k1, K k2, K k3] 
    { 
     get 
     { 
      if (_getFunc3 == null) throw new ArgumentException(); 
      return _getFunc3(k1, k2, k3); 
     } 
     set 
     { 
      if (_getFunc3 == null) throw new ArgumentException(); 
      _setFunc3(k1, k2, k3, value); 
     } 
    } 

    public Transform(Func<K, T> getFunc) { this._getFunc1 = getFunc; } 
    public Transform(Func<K, T> getFunc, Action<K, T> setFunc) 
     : this(getFunc) 
    { 
     this._setFunc1 = setFunc; 
    } 
    public Transform(Func<K, K, T> getFunc) { this._getFunc2 = getFunc; } 
    public Transform(Func<K, K, T> getFunc, Action<K, K, T> setFunc) 
     : this(getFunc) 
    { 
     this._setFunc2 = setFunc; 
    } 
    public Transform(Func<K, K, K, T> getFunc) { this._getFunc3 = getFunc; } 
    public Transform(Func<K, K, K, T> getFunc, Action<K, K, K, T> setFunc) 
     : this(getFunc) 
    { 
     this._setFunc3 = setFunc; 
    } 
} 

Vous permettant de créer des exemples de classes comme suit:

class TransformUser 
{ 
    int[, ,] _array = new int[4, 4, 4]; 

    public Transform<int, int> Normal; 
    public Transform<int, int> Transformed; 

    public TransformUser() 
    { 
     for (int i = 0; i < 4; i++) 
      for (int j = 0; j < 4; j++) 
       for (int k = 0; k < 4; k++) 
        _array[i, j, k] = i * j * k; 

     Normal = new Transform<int, int>((x, y, z) => _array[x, y, z]); 
     Transformed = new Transform<int, int>((x, y, z) => _array[x, y/2, z]); 
    } 
} 

Avec une utilisation comme suit:

TransformUser tu = new TransformUser(); 
Console.WriteLine(tu.Normal[2, 3, 2]); 
Console.WriteLine(tu. Transformed[2, 3, 2]); 
0

Voici une option:

private Terrain[,,] rawArray = ...; 
private View view = new View(rawArray); 


private class View 
{ 
    private class TransformedView 
    { 
     private Terrain[,,] array; 
     public TransformedView(Terrain[,,] array) 
     { 
      this.array = array; 
     } 

     public Terrain this[int x, int y, int z] 
     { 
      get { ... } 
      set 
      { 
       this.array[2*x, 3*z, -y] = value; 
      } 
     } 
    } 

    private Terrain[,,] array; 
    public readonly TransformedView Transformed; 
    public View(Terrain[,,] array) 
    { 
     this.array = array; 
     Transformed = new TransformedView(array); 
    } 

    public Terrain this[int x, int y, int z] 
    { 
     get { ... } 
     set 
     { 
      this.array[x, z, y] = value; 
     } 
    } 
} 
Questions connexes