c# - 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);
}
}
}
解决方案
当您的代码超过 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;
}
}
//...
}
推荐阅读
- python - 如何向执行命令的用户发送 DM 并发送到频道
- python - ValueError: `.fit()` 的输入应该有 4 级。在 CNN 中有形状的数组吗?
- python - 使用 Python Selenium 循环遍历 CSV 文件中的 URL 链接
- usb - 在追溯中区分具有相同产品/供应商 ID 的两个 USB 设备的方法
- javascript - 如何动态地使接口键成为必需(或使其成为可选)
- python - Selenium 中的 Instagram XPath 不起作用?(Python)
- javascript - 如何检查输入是否只包含0和1?
- elasticsearch - 编写一个查询而不是四个查询
- grails - Grails 2.4.4 与 Java 8 的兼容性
- python - 如何在临时目录中写入和读取 txt 文件?