Свойство Getter запускается так, что никто его не называет - PullRequest
3 голосов
/ 12 января 2010

Я работаю в .net 3.5. У меня есть класс «A», который имеет стек и свойство getter, которое при вызове удаляет первый элемент в стеке и получает следующий.

После инициализации класса я увидел, что геттер работает без вызова и удаляет верхний элемент в стеке, что дает мне плохие результаты. Точка останова в геттере не показала никого, проходящего через нее.

Когда я изменяю свойство на функцию, стек возвращается нормально.

Я был бы рад, если бы кто-то мог объяснить, почему это так.

Вот упрощенный класс:

 public class A
    {
        private Stack<string> Urls;

        public A(string title, string[] array)
        {
            Urls = new Stack<string>();
            foreach (string s in array)
            {
                Urls.Push(s);
            }
        }

        public string Url
        {
            get { return Urls.Peek(); }
        }
        public string NextUrl
        {
            get{
            if (Urls.Count > 1)
                { Urls.Pop(); } 
            return Urls.Peek(); 
            };
        }            
    }

Ответы [ 4 ]

9 голосов
/ 12 января 2010

Во-первых, создание свойства accessor для изменения состояния обычно является плохой идеей. Максимум, что он должен сделать, это лениво инициализировать что-то - или, возможно, дать переменное значение (как DateTime.Now делает).

Во-вторых, вы, вероятно, видите это, если работаете под отладчиком - он обращается к свойствам во время пошагового выполнения кода. Это, вероятно, объясняет, почему точка останова тоже не была достигнута.

2 голосов
/ 12 января 2010
Urls.Pop();

хочет быть

return Urls.Pop();

, поскольку возвращает значение , а одновременно удаляет его из списка


На самом деле, перечитав ваш вопрос, похоже, потому что отладчик оценивает свойства. Если вы запускаете приложение без отладчика, возникает ли у вас такая же проблема?

1 голос
/ 12 января 2010

ИМО, проблема здесь в том, что свойство имеет неочевидные побочные эффекты; это должен быть метод:

    public string GetNextUrl() { /* */ }

В противном случае плохие вещи случаются повсеместно (отладчик, привязка данных и т. Д.). Не думайте, что кто-то читает свойство только один раз.

Единственным разумным использованием побочных эффектов в свойствах являются такие вещи, как отложенная загрузка, отложенная инициализация и т. Д. Он по-прежнему должен сообщать одно и то же значение при последовательном вызове без каких-либо явных мутационных вызовов.

1 голос
/ 12 января 2010

Это плохой дизайн, я думаю. Метод доступа get не должен изменять объект таким образом, чтобы при последующих вызовах возникали разные результаты.

...