Getter property is run without anyone calling it

北城余情 提交于 2019-12-10 20:48:41

问题


I'm working in .net 3.5. I have a class "A" which has a stack and a getter property which, when called, removes the first item in the stack and retrieves the next one.

After initializing the class, I saw that the getter works without being called, and removes the top item in the stack, thus giving me bad results. A breakpoint in the getter did not show anyone passing through it.

When I change the property to a function, the stack is returned ok.

I'd be happy if someone could explain why is that.

Here is the simplified class:

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

回答1:


Firstly, making a property accessor change the state is generally a bad idea. The most it should do is lazily initialize something - or possibly give a volatile value (like DateTime.Now does).

Secondly, you're probably seeing this if you're running under the debugger - it accesses properties while you're stepping through code. That would probably explain why the breakpoint wasn't being hit, too.




回答2:


Urls.Pop();

wants to be

return Urls.Pop();

as it returns the value and removes it from the list at the same time


Actually having re-read your question, it looks like it is because the debugger evaluates properties. If you run the application without the debugger do you get the same problem?




回答3:


This is bad design I think. A get accessor should not mutate the object in a way that causes different results on subsequent calls.




回答4:


IMO, the problem here is having a property that has non-obvious side-effects; this should be a method:

    public string GetNextUrl() { /* */ }

Otherwise bad things happen everywhere (the debugger, data-binding, etc). Don't assume that somebody only reads a property once.

The only sensible use of side-effects in properties is things like lazy-loading, deferred initialization, etc. It should still report the same value when called sequentially without any other obvious mutating calls.



来源:https://stackoverflow.com/questions/2048790/getter-property-is-run-without-anyone-calling-it

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!