首页 > 解决方案 > Setter 不断递归调用自己

问题描述

我正在用 C# 练习事件和委托。当我运行代码时,我得到 Process is terminate due to StackOverflowException,因为 setter 由于以下行而递归调用自身:

CurrentPrice = value; //inside the setter of CurrentPrice

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

namespace PriceEvent
{

    public class PriceChangingEvent : EventArgs
    {

        public int Counter = 0; 

        public int CurrentPrice {

            get
            {
                return CurrentPrice; 

            }

            set
            {
                // only invoke the Event when the Class PriceChangingEvent has been instantiated
                if (Counter > 0) // that is when we are not using the constructor
                {
                    CallPriceChanger(this);
                }

                CurrentPrice = value;
                ++Counter; 

            }

        }
        public int NewPrice { get; set; }

        // 2 args Constructor , constructor invokes setter 
        public PriceChangingEvent(int currentprice, int newprice)
        {
            this.CurrentPrice = currentprice;  // invokes the setter of CurrentPrice
            this.NewPrice = newprice;

        }


         //1. define a delegate between publisher and subscribers
         //source publisher who triggers the event,  
        public delegate void CurrentPriceChangeEventHandler(object source, PriceChangingEvent PriceEvent);

        // 2. define an event
        public event CurrentPriceChangeEventHandler PriceChange;

        // 3. raise the event, OnDataTrained is the method which calls the delegate
        protected virtual void OnCurrentPriceChange(PriceChangingEvent PriceEvent)
        {
           PriceChange.Invoke(this, PriceEvent);
        }

        // 3.Function which raises the event, OnPriceChanger is the method which calls the delegate
        protected virtual void OnPriceChanger(PriceChangingEvent PriceChangingEvent)
        {
            // this: the class 
            PriceChange.Invoke(this, PriceChangingEvent);
        }


        // Function to call the function OnPriceChanger
        public void CallPriceChanger(PriceChangingEvent PriceChangingEvent)
        {

            OnPriceChanger(PriceChangingEvent);

        }

    }

    class Program
    {
        static void Main(string[] args)
        {

            PriceChangingEvent p = new PriceChangingEvent(20, 30);

            p.CurrentPrice = 45;



        }

        //subscribers

        public static void Display(PriceChangingEvent p)
        {
            Console.WriteLine("Current Price has been changed to {0}", p.CurrentPrice);

        }
    }
}

标签: c#.net

解决方案


当您的代码超过 getter 或 setter 的最小值时,您需要该属性的支持字段

private int _currentPrice;

public int CurrentPrice
{
    get
    {
        return _currentPrice; 

    }
    set
    {
        if (Counter > 0) // that is when we are not using the constructor
        {
            CallPriceChanger(this);
        }

        _currentPrice = value;
        ++Counter; 
    }
}

您可以进一步使用支持字段来简化代码,构造函数现在可以直接设置支持字段,并且您不再需要该Counter值。

public class PriceChangingEvent : EventArgs
{
    public PriceChangingEvent(int currentprice, int newprice)
    {
        _currentPrice = currentprice;  
        NewPrice = newprice;
    }

    private int _currentPrice;
    public int CurrentPrice
    {
        get
        {
            return _currentPrice; 
        }
        set
        {
            CallPriceChanger(this);
            _currentPrice = value;
        }
    }

    //...
}

推荐阅读