【发布时间】: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 应该只是事件的参数,而不是实现事件本身。您对类的设计及其命名以及变量/方法参数/等。相当混乱而且不是很理智......