代码之家  ›  专栏  ›  技术社区  ›  Loren Pechtel

C#数组与属性

  •  1
  • Loren Pechtel  · 技术社区  · 16 年前

    我对C#还很陌生,我不知道如何表达一些非常简单的东西。

    我有一个私人的3D阵列。

    我对公开内容以供阅读的函数没有问题:

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

    但我还需要一个内部函数,它通过坐标变换提供读/写访问。

    似乎没有办法指定setter。

    [] 而不是 () 但这会导致编译器认为它是一个数组定义,当然它会到处呕吐。在谷歌搜索其他地方时,我发现很多人试图修改某个返回引用类型的字段,这当然失败了,但这个数组充满了枚举,而不是引用类型。

    SetTile(x, y, z, terrain) 功能,但能够访问它作为一个数组是如此清楚&优雅,但这似乎是不可能的。

    3 回复  |  直到 16 年前
        1
  •  4
  •   dtb    16 年前

    您可以使用 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;
            }
        }
    }
    
        2
  •  0
  •   Patrick    16 年前

    这里有一个选择:

    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;
            }
        }
    }
    
        3
  •  0
  •   Yuriy Faktorovich    16 年前

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