Help to understand example console application code

vitaminchik 486 Reputation points
2023-03-19T15:03:54.9566667+00:00

Hello. I'm breaking down the topic by class in C#. I found an example of code. I do not quite understand a few lines of code:

StackItem _stackItem = null;

public StackItem Item { get; set; }

public static MyStack Concat(params MyStack[] elementsOfArray)
result = element._stackItem.Value;
element._stackItem = element._stackItem.Item;
}

How does the method Concat() change the value of an object in variable -result? I've been debugging, but I still don't understand. And another question, what does the class field store Item Prev?

Here is an example code:

namespace TheFourthProgram
{
    public class MyStack
    {
        int _count = 0;
        string? _top;
        StackItem _stackItem = null;

        public int Count
        {
            get => _count;
        }
        public StackItem StItem
        {
            get => _stackItem;
            set => _stackItem = value;
        }
        public string Top
        {
            get
            {
                if (_count == 0)
                    return null;
                return _top;
            }
        }
        public int Size
        {
            get => _count;
        }

        public MyStack(params string[] elementsOfArray)
        {
            Add(elementsOfArray);
        }

        // Adding an element to the stack. 
        public void Add(string value)
        {
            _top = value;
            _count++;
            _stackItem = new StackItem(_stackItem, value);
        }

        public void Add(string[] values)
        {
            for (int i = 0; i < values.Length; i++)
            {
                Add(values[i]);
            }
        }

        public void Add(List<String> values)
        {
            foreach (var value in values)
            {
                Add(value);
            }
        }

        // Removing an element from the stack.
        public string Pop()
        {
            string? result = null;
            try
            {
                if (_stackItem != null)
                {
                    result = _stackItem.Value;
                    _stackItem = _stackItem.Item;
                    _count--;
                    _top = _stackItem != null ? _stackItem.Value : null;
                }
                else
                {
                    throw new EmptyStackException();
                }
            }
            catch (EmptyStackException ex)
            {
                Console.WriteLine(ex.Message);
            }
            return result;
        }
        static int j = 0;

        /// <summary>
        /// Method that combines an unlimited number of objects.
        /// </summary>
        /// <param name="elementsOfArray">Array of type objects MyStack.</param>
        /// <returns>New stack.</returns>
        public static MyStack Concat(params MyStack[] elementsOfArray)
        {
            MyStack stack = new MyStack();
            string? result;
            foreach (MyStack element in elementsOfArray)
            {
                List<string> list = new List<string>(element._count);
                for (int i = 0; i < element._count; i++)
                {
                    result = element._stackItem.Value;
                    element._stackItem = element._stackItem.Item;
                    list.Add(result);
                }
                if (j == 0)
                {
                    stack.Add(list);
                }
                else
                {
                    stack.Add(list);
                }
                j++;
            }
            return stack;
        }
    }
}

 public class StackItem
    {
        public StackItem Item { get; set; }
        public string Value { get; set; }
 
        static string? _previousElement;
        static string? _top;

        public StackItem(StackItem stackItem, string value)
        {
            _previousElement = _top;
            _top = value;
            Item = stackItem;
            Value = value;
        }
    }


class Program
    {
        static void Main(string[] args)
        {
            MyStack elements = new("a", "b", "c");
            // size = 3, Top = 'c'
            Console.WriteLine($"size = {elements.Size}, Top = '{elements.Top}'");
            var s = MyStack.Concat(new MyStack("a", "b", "c"), new MyStack("1", "2", "3"), new MyStack("A", "B", "C"));
            Console.WriteLine($"size = {s.Size}, Top = '{s.Top}'");
        }
    }
}
Developer technologies C#
{count} votes

Accepted answer
  1. Jack J Jun 25,296 Reputation points
    2023-03-20T13:49:52.3533333+00:00

    @vitaminchik, thanks for the feedback,

    There are some explanations about your question.

    How does the method Concat() change the value of an object in variable -result?

    a. The params MyStack[] elementsOfArray convert the three MyStack object to a MyStack array.

    b. The foreach statement get every MyStack to get the property _stackItem.Values(such as string(a,b,c,1,2,3).

    c. Then we could get every result is "a", "b", "c", 1", "2", "3,"A", "B", "C".

    And another question, what does the class field store Item Prev?

    It used the following class constructor to set the Item property.

     public StackItem(StackItem stackItem, string value)
            {
                _previousElement = _top;
                _top = value;
                Item = stackItem;//-> here used to set the Item property
                Value = value;
            }
    
    public void Add(string value)
            {
                _top = value;
                _count++;
                _stackItem = new StackItem(_stackItem, value);
            }
    
    

    When calling Add method, it will call the constructor automatically.

    In a conclusion, this program is used to nest StackItem types, for example, the first is SItem (StackItem type), the value is A, and the nested inside is Item (StackItem type). The value is B, and so on.

    And you could add a watch in visual studio to check his behaviour:

    User's image

    Hope my explanation could help you.

    Best Regards,

    Jack


    If the answer is the right solution, please click "Accept Answer" and upvote it.If you have extra questions about this answer, please click "Comment".

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    1 person found this answer helpful.
    0 comments No comments

2 additional answers

Sort by: Most helpful
  1. Bruce (SqlWork.com) 77,686 Reputation points Volunteer Moderator
    2023-03-20T15:48:37.25+00:00

    this is a pretty poor implementation of a stack, and the use of static variables for _top and _previousElement is suspect. Only one stack instance at a time is supported. also making Item public is also a bad practice. Internal links should be hidden. it should at least be readonly.

    as it just implement a stack of strings, it hard to justify the StackItem class.

    this is a good example of how not to code, and should fail any code review.

    a simpler implementation:

    	public class MyStack
        {
    		List<string> _stack = new List<string>();
    
            public int Count => _stack.Count;
            public int Size => Count;
    
    		// usually called peek
    		public string Top => _stack.Count > 0 ? _stack[_stack.Count-1] : (string) null;
    
            public MyStack(params string[] elementsOfArray)
            {
                Add(elementsOfArray);
            }
    
            public void Add(string value) => _stack.Add(value);
    
            public void Add(IEnumerable<string> values)
    		{
    			foreach (var v in values) _stack.Add(v);
    		}
    
    		public string Pop()
            {
    			if (_stack.Count == 0)
    				return null;
    			var value = _stack[_stack.Count -1];
    			_stack.RemoveAt(_stack.Count -1);
    			return value;
    		}
    
    		public IEnumerable<string> Values => _stack;
    		
            public static MyStack Concat(params MyStack[] elementsOfArray)
            {
                MyStack stack = new MyStack();
    			foreach (var s in elementsOfArray) stack.Add(s.Values);
                return stack;
            }
        }
    

    as an exercise, you could easily make the code generic MyStack<T>

    1 person found this answer helpful.
    0 comments No comments

  2. Karen Payne MVP 35,586 Reputation points Volunteer Moderator
    2023-03-19T20:25:06.5966667+00:00

    Concat creates a new instance of MyStack by way of params Array of MyStack.

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.