我试图创建简单的事件,下面是代码块,但无法正常工作。当我尝试调试时,一旦创建Point对象,它就会在“ Set”属性上抛出“ StackOverFlowException”(甚至在我们分配值p.x = 10之前)。我做错了什么?
using System;
namespace Workshop
{
public class Point
{
public int x
{
get { return x; }
set
{
x = value;
onPointeChanged();
}
}
public int y
{
get { return y; }
set
{
y = value;
onPointeChanged();
}
}
public event EventHandler pointchanged;
private void onPointeChanged()
{
if (pointchanged != null)
pointchanged(this, EventArgs.Empty);
}
}
public class Program
{
public static void Main(String[] args)
{
Point p = new Point();
p.pointchanged += HandleEvent;
p.x = 10;
}
public static void HandleEvent(object obj, EventArgs sender)
{
Console.WriteLine("Event Raised");
}
}
}
谢谢
答案 0 :(得分:4)
您将无限期地调用set
方法,直到耗尽堆栈内存为止。你在做什么
x = value;
您是在调用x
属性的setter,而后者又是x = value
,所以它会自称,依此类推,以此类推,直到永远。
要解决此问题,请引入一个字段:
private int x;
public int X
{
get => x;
set
{
x = value;
OnPointChanged();
}
}
这是使用get
和/或set
后的自定义逻辑创建属性的正确方法。如果您没有OnPointChanged()
逻辑,就可以这样做
public int X { get; set; }
这将为您生成以下代码:
private int x;
public int X { get => x; set => x = value; }
答案 1 :(得分:3)
问题是您要在属性的自身设置器中为其分配值:
public int x
{
get { return x; }
set
{
x = value; // <-- see you are assigning `value` to your `x` property.
onPointeChanged();
}
}
这将无限循环。您需要创建一个后备字段:
private int _myField;
public int BetterNameThanX
{
get { return _myField; }
set
{
_myField = value;
onPointeChanged();
}
}
答案 2 :(得分:1)
您已经定义了属性,并且返回了每个自己的属性,这些属性导致在get
和set
范围上的递归。尝试定义私有attributes
并通过属性公开它:
public class Point
{
private int _x;
public int x
{
get { return _x; }
set
{
_x = value;
onPointeChanged();
}
}
private int _y;
public int y
{
get { return _y; }
set
{
_y = value;
onPointeChanged();
}
}
public event EventHandler pointchanged;
private void onPointeChanged()
{
if (pointchanged != null)
pointchanged(this, EventArgs.Empty);
}
}