我在这里遇到一些问题,我正在使用一个名为Cell
的课程,当我创建每个单元格时,我想要引发一个OnCellCreated
附加的事件IGameViewer
最终。由于一些奇怪的原因,它不起作用,现在我绕过了这个而不是在构造函数中调用IGameViewer.DisplayCell
,但它非常奇怪,因为它从构造函数传递完全相同的对象引用并且它可以工作,但是当我试着用我的事件来做我将得到一个空对象引用。那么有人有任何想法吗?
这是代码
class Cell
{
public delegate void CellChangedHandler(Cell cell);
#region Properties & Fields
private Mark markType = Mark.Empty;
private IGameViewer viewer;
public static event CellChangedHandler OnCellChanged;
public static event CellChangedHandler OnCellCreated;
public readonly Tuple<int, int> pos;
public Mark MarkType {
get { return markType; }
set
{
// Only allow changes to cells without a mark
if (markType.Equals(Mark.Empty))
{
markType = value;
OnCellChanged(this); //Model -> Viewer & Presenter, both can attach to this event
}
}
}
#endregion
#region Constructors
public Cell(IGameViewer viewer, Tuple<int, int> coords)
{
this.viewer = viewer;
this.pos = coords;
OnCellCreated(this); // <- This causes an object null reference exception to be thrown
viewer.DisplayCell(this); // <- This doesn't, even if I reverse the calling order
}
#endregion
}
答案 0 :(得分:3)
您的OnCellCreated
事件为空,因为还没有订阅它。如果你已经在建设者中调用它,调用者如何做到这一点。 ? 如果尚未创建实例(您在构造函数中),则无法订阅实例事件
您可以创建CellFactory
类并将CellCretaed
事件添加到工厂。您要求CellFactory
创建Cell实例,并在创建它之后CellFactory
引发一个事件。当然,您必须在调用工厂方法之前订阅该事件。
答案 1 :(得分:1)
每当提出该事件时,检查该事件是否有订阅者:
public Cell(IGameViewer viewer, Tuple<int, int> coords) {
this.viewer = viewer;
...
if (!Object.ReferenceEquals(null, OnCellCreated))
OnCellCreated(this);
...
}
答案 2 :(得分:0)
正如@Tigran回答的那样,问题是还没有人订阅这个活动。通过在构造函数上调用事件,您期望发生什么?
如果您遵循该模式在.NET类中实现事件,那么这种情况从未发生过。
将您的代码更改为:
class Cell
{
private Mark markType = Mark.Empty;
private IGameViewer viewer;
public static event EventHandler CellChanged;
public readonly Tuple<int, int> pos;
public Cell(IGameViewer viewer, Tuple<int, int> coords)
{
this.viewer = viewer;
this.pos = coords;
viewer.DisplayCell(this);
}
public Mark MarkType {
get { return markType; }
set
{
// Only allow changes to cells without a mark
if (markType.Equals(Mark.Empty))
{
markType = value;
OnCellChanged();
}
}
}
protected virtual void OnCellChanged()
{
var handler = this.CellChanged;
if (handler)
{
handler(this, EventArgs.Empty);
}
}
}