在C#中为什么我不能传递另一个类“EventHandler”引用,我该如何解决?

前端之家收集整理的这篇文章主要介绍了在C#中为什么我不能传递另一个类“EventHandler”引用,我该如何解决?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
如果我有ClassA有一个公共事件,SomeEvent和ClassC有方法addListener接受一个EventHandler引用,为什么ClassB不能有一行说c.addListener(ref a.SomeEvent)?如果我尝试我得到一个编译器错误,说:“事件’ClassA.SomeEvent’只能出现在=或 – =的左侧(除了在类型”ClassA“内使用时).

为什么存在这种限制?而且在与我的结构相当接近的地方我怎么可以绕过呢?

我是一个C#新手;任何帮助将不胜感激.谢谢!

class ClassA {
    public event EventHandler SomeEvent;
}

ClassB{
    public ClassB() {

        ClassA a = new ClassA();
        ClassC c = new ClassC();
        c.addListener(ref a.SomeEvent);  //Compile error
    }
}

class ClassC {
    public void addListener(ref EventHandler handler) {
        handler += onEvent;
    }

    private void onEvent(object sender,EventArgs e) {
        //do stuff
    }

}

解决方法

event关键字为私有委托对象创建一个访问器.一个属性完全相同的东西,它限制了对私有域的访问.当您使用属性而不是事件时,您的代码片段将失败,出现类似错误
class ClassA {
    public int Property { get; set; }
  }
  class ClassB {
    public ClassB() {
      ClassA a = new ClassA();
      ClassC c = new ClassC();
      c.setValue(ref a.Property);   // CS0206
    }
  }
  class ClassC {
    public void setValue(ref int value) {
      value = 42;
    }
  }

现在很容易看到,编译器没有办法确保setValue()方法使用属性setter.也不能知道“值”参数是具有设置器或普通字段的属性.

事件不太清楚,因为在工作中有很多语法糖.这个声明

public event EventHandler SomeEvent;

实际生成代码

private EventHandler _SomeEvent;
public event SomeEvent {
  add    { _SomeEvent += new EventHandler(value); }
  remove { _SomeEvent -= new EventHandler(value); }
}

添加和删​​除访问器等同于属性的get和set访问器,它们阻止代码混淆私有_SomeEvent字段.按照惯例,当你使用=时,add访问器被调用,用 – =调用remove.将此与之前给出的一个属性进行比较.同样的问题,你不能使用ref关键字,ClassC.addListener()将无法知道处理程序实际上是一个事件而不是委托对象.如果编译器会传递_SomeEvent,那么使用访问器的点就会丢失.

您可以重组代码解决这个问题:

class ClassC {
    public EventHandler getListener() {
      return new EventHandler(onEvent);
    }
    private void onEvent(object sender,EventArgs e) { }
  }
...
      a.SomeEvent += c.getListener();

最后一个注意事项:事件和属性之间的对称性有点丢失,如果不明确写入,C#编译器会自动生成add / remove访问器.它不为财产做这个.它会使自动属性更容易:

property int Property;

但是,这需要为该语言添加一个新的关键字,C#团队真的不喜欢.其他语言,如VB.NET和C/C++LI确实有这个关键字.

原文链接:https://www.f2er.com/csharp/95406.html

猜你在找的C#相关文章