C # Управление доступом к элементу свойства массива - PullRequest
2 голосов
/ 12 октября 2011

Я хотел бы предоставить доступ к внутреннему массиву с помощью свойства, но контролировать доступ к элементам массива.

Я написал простой пример, который может объяснить мою проблему лучше, чем я сам.

В этом примере я предоставляю класс 'Fail' и класс 'Controlled'. Второй работает так, как мне хотелось бы, но подход немного другой, и он полезен только с одним массивом.

У меня следующий вопрос: А что если мне нужно иметь два разных массива и, следовательно, два разных свойства?

Как это сделать?

Спасибо.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("The Fail Class:");

            MyFailClass MyFailTestClass = new MyFailClass(5);
            MyFailTestClass.MyList[2] = 11;
            if (MyFailTestClass.Modified) {
                Console.WriteLine("Right");
            } else {
                Console.WriteLine("Error");
            }



            Console.WriteLine("The Controlled Class:");

            MyControlledClass MyControlledTestClass = new MyControlledClass(5);
            MyControlledTestClass[2] = 11;
            if (MyControlledTestClass.Modified) {
                Console.WriteLine("Right");
            } else {
                Console.WriteLine("Error");
            }

            Console.ReadKey();
        }
    }

    public class MyFailClass
    {
        // Property 
        public byte[] MyList
        {
            get
            {
                return myList;
            }
            set  // <--------- Never enters here if I set a concrete array element
            {
                Modified = !myList.Equals(value);
                myList = value;
            }
        }
        public bool Modified { get; set; }

        // Constructor
        public MyFailClass(int elements)
        {
            myList = new byte[elements];
        }

        private byte[] myList;
    }

    public class MyControlledClass
    {
        // Property 
        public byte this[int index]
        {
            get
            {
                return myList[index];
            }
            set
            {
                Modified = !myList[index].Equals(value);
                myList[index] = value;
            }
        }
        public bool Modified { get; set; }

        // Constructor
        public MyControlledClass(int elements)
        {
            myList = new byte[elements];
        }

        private byte[] myList;
    }
}

Ответы [ 2 ]

2 голосов
/ 12 октября 2011

Вы можете рассмотреть замену вашего свойства массива, скажем, на ObservableCollection<T>.

Возможно, вы выставите свойство как IList<T>, поскольку тот факт, что его можно наблюдать, является внутреннимПодробности реализации.

public class MyClass
{
    public IList<byte> MyList
    {
        get { return _myList; }
    }
    private IList<byte> _myList = new ObservableCollection<byte>();

    ...
}

Реализация MyClass должна обрабатывать _myList PropertyChanged и CollectionChanged события.

Обратите внимание, что обычно вам не нужен установщик длясвойство коллекции - если вызывающий объект хочет заменить список, он может вызвать:

myClass.MyList.Clear();

, затем добавить новые элементы.

1 голос
/ 12 октября 2011

Если вам нужны два массива, то, разумеется, вам может понадобиться три или четыре (я точно не знаю, но, похоже, так и происходит).

В этом случае я хотел бы рассмотреть возможность создания класса, который является совокупностью вашего "MyControlledClass"

public class IndexedClass
{
    // Property 
    public byte this[int index]
    {
        get
        {
            return myList[index];
        }
        set
        {
            Modified = !myList[index].Equals(value);
            myList[index] = value;
        }
    }

}

public class IndexedClassGroup
{
    // Property 
    public IndexedClass this[int index]
    {
        get
        {
            return myList[index];
        }
        set
        {
            Modified = !myList[index].Equals(value);
            myList[index] = value;
        }
    }

}

Тогда вы можете получить доступ к таким вещам, как двумерный массив.

Лично я немного подозреваю в том, что теоретически можно представить массив как концепцию получения / установки, так что я не очень разбираюсь в тонкостях этого. Использует ли класс массив или список, или что-то вроде частной реализации, а не открытого свойства. Если вы собираетесь представить что-то, выставьте ICollection <> или IEnumerable <> и разрешите это внутренне в массив. Во всяком случае, мои два цента.

...