【问题标题】:Setter keeps calling itself recursivelySetter 不断递归调用自己
【发布时间】:2019-06-28 17:27:26
【问题描述】:

我正在用 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);

        }
    }
}

【问题讨论】:

  • 您帖子底部的“Lorem ipsum...”文字是什么意思?在任何情况下,您都需要提供一个私有支持字段以避免此错误。 private int _currentPrice;。然后在 setter 中设置该变量,并从 getter 中返回它。
  • 你尝试过 Getter - 它也是递归的。
  • 顺便说一句,我注意到您的PriceChangingEvent 类派生自EventArgs 并实现了一个事件PriceChange。 EventArg(顾名思义)是与引发事件相关的参数/数据(它们包含需要/应该与引发事件一起传递的任何数据)。您的类名“PriceChangingEvent”表明它代表一个事件,而不是事件参数,但它派生自EventArg。但不仅如此,PriceChangingEvent 也不代表一个事件,但PriceChangingEvent.PriceChange 是。 (1/2)
  • (2/2) PriceChangingEvent(实际上是一个 EventArg)有一个事件也没有意义,因为 EventArgs 应该只是事件的参数,而不是实现事件本身。您对类的设计及其命名以及变量/方法参数/等。相当混乱而且不是很理智......

标签: c# .net


【解决方案1】:

当您的代码超过 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;
        }
    }

    //...
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-03-02
    • 1970-01-01
    • 2019-10-04
    • 1970-01-01
    • 2016-04-05
    • 2023-03-18
    • 2011-02-11
    • 1970-01-01
    相关资源
    最近更新 更多