微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

C#使用自定义参数的继承事件

我试图在自定义参数的接口中指定一个事件.我需要将event参数作为一个对象.我试图尽可能地删除以下代码.我目前收到以下错误.

ArgumentNullException: Argument cannot be null.
Parameter name: obj
LittleObject.IObject.add_ChangeEvent (System.EventHandler`1 value) 
(at LittleObject.cs line : [where the comment is])

public class ChangeEventArgs : EventArgs {
    public ChangeEventArgs(SomeClass c){ someClass = c;}
    public SomeClass someClass;
}


public interface IObject {
    void OnChangeEvent(ChangeEventArgs e);
    event EventHandler<ChangeEventArgs> ChangeEvent;
}


public class LittleObject : IObject{    

    public event EventHandler<ChangeEventArgs> ChangeEvent;

    public fireEvent(){
        OnChangeEvent(new ChangeEventArgs(new SomeClass()));
    }

    event EventHandler<ChangeEventArgs> IObject.ChangeEvent{
        add{                                // error here
            lock (ChangeEvent) {
                ChangeEvent += value;
             }
        }
        remove{
            lock (ChangeEvent){
                ChangeEvent -= value;
            }
        }
    }

    public void OnChangeEvent(ChangeEventArgs e){
        if(ChangeEvent != null) {
            ChangeEvent(this,e);
        }
    }
}


public class Main {

    IObject currentObject;

    void init(){
        currentObject = new IObject();
        currentObject.ChangeEvent += new EventHandler<ChangeEventArgs>(OnChangeEvent);
    }

    void doStuff(){
        currentObject.fireEvent();
    }

    public void OnChangeEvent(object sender,ChangeEventArgs e) {
        SomeClass someClass = e.someClass;
    }
}

解决方法

这段代码非常混乱,但我相信你得到异常的原因是因为你锁定了一个空引用.

当你这样做时:

add
{
    lock (ChangeEvent) { ... }
}

编译器实际上使用支持ChangeEvent事件的私有字段(参见field-like event).请注意,此字段的初始值为null(未明确分配初始值,例如通过字段初始值设定项).

现在有人第一次订阅“包装”事件(someObject.ChangeEvent = …)时,会调用自定义添加访问者,导致尝试锁定该字段引用的对象(锁实际需要对象标题中的一些数据称为“同步块”.当然,没有这样的对象,这就是锁定爆炸的原因.

至于奇怪的obj参数,那就是Monitor.TryEnter(object obj,ref bool lockTaken)中的那个,这是C#lock语句编译成的(C#的早期版本针对不同的方法).

老实说,我会强烈考虑重新设计这整段代码.

编辑:澄清了包装事件的使用.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐