我试图在自定义参数的接口中指定一个事件.我需要将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 举报,一经查实,本站将立刻删除。