2009-09-03 2 views
1

Я довольно чертовски новичок в C#, и я не могу понять, как выразить что-то довольно простое.C# Массивы и свойства

У меня есть массив 3D, который является частным.

У меня нет никаких проблем с функцией, которая выставляет содержимое читать:

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

, но я также хочу внутреннюю функцию, которая обеспечивает чтение/запись с преобразованием координат чтения.

Кажется, что нет способа указать сеттер.

Глядя на сайт Microsoft, кажется, что он хочет [], а не (), но это приводит к тому, что компилятор считает, что это определение массива и, конечно же, он заперт повсюду. Googling в другом месте я нахожу много людей, пытающихся изменить поле чего-то, возвращающего ссылочный тип, который, конечно, терпит неудачу, но этот массив полон перечислений, а не ссылочных типов.

Конечно, я могу написать функцию SetTile(x, y, z, terrain), но доступ к ней как массиву гораздо более ясен. & элегантный, но это кажется невозможным.

+1

Ты говоришь, что вы хотели бы реализовать индексатор для своего класса? –

ответ

4

Вы можете определить «вид» класс с indexer, которая в основном свойство с аргументами:

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

Такая же проблема, как с ответом шелковицы - мне нужен как необработанный вид, так и преобразованный вид. –

+0

Эй, dtb, могу ли я получить мнение о своем классе? –

+0

Я согласен с тем, что индексаторы - это то, что я хочу (почему отдельный термин?), Но я не следую тому, что вы здесь делаете. Это обеспечивает преобразованный массив, но я не вижу, как он также делает исходный. –

0

Чтобы продлить на ответ DTB, я написал следующее преобразование класс:

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; 
    } 
} 

Предоставление вам возможности создания типовых классов следующим образом:

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]); 
    } 
} 

При использовании, как в следующем:

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

Вот один вариант:

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; 
     } 
    } 
} 
Смежные вопросы