C#自定义事件为空

C#自定义事件为空,c#,winforms,events,C#,Winforms,Events,我对这里的事件有意见 在你写“复制品”之前,我要说我已经做了很多了,我不太擅长编程,这就是为什么我还要问这个问题 问题是我的活动没有启动 调试器显示:=>“OnCollision为空” 编辑:调试器部分 迎面相撞是我的事 谢谢你的帮助:D 这是我的活动 public class CollisionEventArgs : EventArgs { public bool Hit { get { return hit; } } private bool hit; publi

我对这里的事件有意见

在你写“复制品”之前,我要说我已经做了很多了,我不太擅长编程,这就是为什么我还要问这个问题

问题是我的活动没有启动

调试器显示:=>“OnCollision为空”

编辑:调试器部分

迎面相撞是我的事

谢谢你的帮助:D

这是我的活动

public class CollisionEventArgs : EventArgs
{
    public bool Hit { get { return hit; } }
    private bool hit;

    public CollisionEventArgs(bool _hit)
    {
        this.hit = _hit;
    }
}
HitControl

public delegate void CollisionHandler(object current, CollisionEventArgs cea);
public class HitControl : Button
{
    public event CollisionHandler OnCollision;
    public bool IsHit
    {
        get { return isHit; }
        set
        {
            if (OnCollision != null)
            {
                if (this.Width > 100)
                OnCollision(this, new CollisionEventArgs(true));
            }
        }
    }
    public bool isHit;

    public HitControl()
    { }
}
方法

 private void hitControl1_OnCollision_1(object current, CollisionEventArgs cea)
    {
        MessageBox.Show("a");

    }
设计器中的代码[Sub]

// 
        // hitControl1
        // 
        this.hitControl1.IsHit = false;
        this.hitControl1.Location = new System.Drawing.Point(115, 183);
        this.hitControl1.Name = "hitControl1";
        this.hitControl1.Size = new System.Drawing.Size(175, 23);
        this.hitControl1.TabIndex = 1;
        this.hitControl1.Text = "hitControl1";
        this.hitControl1.UseVisualStyleBackColor = true;
        this.hitControl1.OnCollision += new CollisionHandler(this.hitControl1_OnCollision_1);

问题是在事件连接之前设置了
IsHit
属性。要安全触发事件,请使用以下语法,而不是直接调用:

OnCollision?.Invoke(this, new CollisionEventArgs(true));
?。
(所谓的Elvis)操作符首先检查
碰撞
是否为
,只有在这种情况下才调用
调用
方法,该方法基本上执行事件。直接使用
OnCollision(sender,new-CollisionEventArgs(true))
不起作用,因为当没有事件订户时,
OnCollision
null
并引发
NullReferenceException

如果您使用的是不支持
?。
运算符的早期版本的C#,您可以执行以下操作:

var handler = OnCollision;
if ( handler != null )
{
   handler(this, new CollisionEventArgs(true));
}

正如我所演示的,将当前实例存储在单独的变量中比直接使用
OnCollision
更安全,因为它可能会在多线程环境中导致问题。有关更多信息,请参阅答案。幸运的是,
?。
这不会发生,因为它已经以线程安全的方式构建,并且基本上在后台做相同的事情

问题在于
IsHit
属性在事件连接之前设置为。要安全触发事件,请使用以下语法,而不是直接调用:

OnCollision?.Invoke(this, new CollisionEventArgs(true));
?。
(所谓的Elvis)操作符首先检查
碰撞
是否为
,只有在这种情况下才调用
调用
方法,该方法基本上执行事件。直接使用
OnCollision(sender,new-CollisionEventArgs(true))
不起作用,因为当没有事件订户时,
OnCollision
null
并引发
NullReferenceException

如果您使用的是不支持
?。
运算符的早期版本的C#,您可以执行以下操作:

var handler = OnCollision;
if ( handler != null )
{
   handler(this, new CollisionEventArgs(true));
}

正如我所演示的,将当前实例存储在单独的变量中比直接使用
OnCollision
更安全,因为它可能会在多线程环境中导致问题。有关更多信息,请参阅答案。幸运的是,
?。
这不会发生,因为它已经以线程安全的方式构建,并且基本上在后台做相同的事情

您在IsHit属性中触发事件,但从未在属性的集合部分设置IsHit backing字段。@Guardian,您有IsHit变量和一个名为IsHit的属性。通常,isHit是私有的,因此在类之外无法访问它,然后针对该类编程的任何人都将使用公共isHit属性来设置值。在属性的set部分,您将调用
isHit=value但您从未调用过它,因此isHit从未改变初始值。您在isHit属性中触发事件,但从未在属性的集合部分设置isHit后备字段。@Guardian,您有isHit变量和一个名为isHit的属性。通常,isHit是私有的,因此在类之外无法访问它,然后针对该类编程的任何人都将使用公共isHit属性来设置值。在属性的set部分,您将调用
isHit=value
但你从未调用过它,因此它从未从初始值更改。我已更新了我的答案
发件人
应为
。在这种情况下,我已在答案中替换了它。代码应该去而不是
OnCollision(这是新的CollisionEventArgs(true))行在
IsHit
setter。在哪一行?您应该在调试器中运行此命令,并查看它何时实际通过映像中哪个变量是
null
?@Guardian,可能是行
公共委托void CollisionHandler(对象当前,CollisionEventArgs cea)
是在您使用它的类之外定义的吗?回顾VS2005中的旧代码,当时我声明委托始终在类中定义。我已更新了答案
sender
应该是
this
,在这种情况下,我已在答案中替换了它。代码应该去而不是
OnCollision(这是新的CollisionEventArgs(true))行在
IsHit
setter。在哪一行?您应该在调试器中运行此命令,并查看它何时实际通过映像中哪个变量是
null
?@Guardian,可能是行
公共委托void CollisionHandler(对象当前,CollisionEventArgs cea)
是在您使用它的类之外定义的吗?回顾VS2005中的旧代码,当我声明委托时,它们总是在类中定义的。