gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-30 14:16:34 25 4
gpt4 key购买 nike

我正在尝试使用自定义参数在接口(interface)中指定一个事件。我需要事件参数是一个对象。我试图尽可能地删除以下代码。我目前收到以下错误。

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;
}
}

最佳答案

这段代码相当困惑,但我相信你得到异常的原因是因为你锁定了一个null-reference。

当你这样做时:

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

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

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

至于奇怪的obj 参数,那是来自Monitor.TryEnter(object obj, ref bool lockTaken) 的参数。 ,这是 C# lock 语句编译后的结果(以前版本的 C# 针对不同的方法)。

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

编辑:阐明了包装事件的使用。

关于使用自定义参数的 C# 继承事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7322029/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com