The Getter property is started without calling it.

I work in .net 3.5. I have a class "A" that has a stack and a getter property that, when called, removes the first element on the stack and retrieves the next.

After initializing the class, I saw that the getter works without a call and removes the top element on the stack, which gives me bad results. The breakpoint at the getter did not show anyone passing through it.

When I change a property to a function, the stack returns normally.

I would be glad if someone could explain why.

Here is a 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(); }; } } 
+3
source share
4 answers

First, if you change the property of accessing an object, the state is usually bad. The most he has to do is lazily initialize something - or perhaps give a mutable value (like DateTime.Now ).

Secondly, you probably see this if you work under the debugger - it accesses the properties while you go through the code. This probably explains why the breakpoint didn’t hit either.

+9
source
 Urls.Pop(); 

wants to be

 return Urls.Pop(); 

when it returns a value and at the same time removes it from the list


Actually, after re-reading your question, it seems that this is because the debugger evaluates the properties. If you run the application without a debugger, do you get the same problem?

+2
source

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

+1
source

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 (debugger, data binding, etc.). Do not assume that someone only reads the property once.

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

+1
source

Source: https://habr.com/ru/post/1334861/


All Articles