在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确实有这个关键字.

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

相关推荐


原文地址:http://msdn.microsoft.com/en-us/magazine/cc163791.aspx 原文发布日期: 9/19/2005 原文已经被 Microsoft 删除了,收集过程中发现很多文章图都不全,那是因为原文的图都不全,所以特收集完整全文。 目录 前言 CLR启动程序
前言 随着近些年微服务的流行,有越来越多的开发者和团队所采纳和使用,它的确提供了很多的优势也解决了很多的问题,但是我们也知道也并不是银弹,提供优势的同时它也给我们的开发人员和团队也带来了很多的挑战。 为了迎接或者采用这些新技术,开发团队需要更加注重一些流程或工具的使用,这样才能更好的适应这些新技术所
最近因为比较忙,好久没有写博客了,这篇主要给大家分享一下PLINQ中的分区。上一篇介绍了并行编程,这边详细介绍一下并行编程中的分区和自定义分区。 先做个假设,假设我们有一个200Mb的文本文件需要读取,怎么样才能做到最优的速度呢?对,很显然就是拆分,把文本文件拆分成很多个小文件,充分利用我们计算机中
在多核CPU在今天和不久的将来,计算机将拥有更多的内核,Microsoft为了利用这个硬件特性,于是在Visual Studio 2010 和 .NET Framework 4的发布及以上版本中,添加了并行编程这个新特性,我想它以后势必会改变我们的开发方式。 在以前或者说现在,我们在并行开发的时候可
c语言输入成绩怎么判断等级
字符型数据在内存中的存储形式是什么
c语言怎么求字符串的长度并输出
c语言函数的三种调用方式是什么
c语言中保留两位小数怎么表示
double的输入格式符是什么
长整型输出格式是什么
C语言中文件包含的命令关键字是什么
c程序如何编写x的y次方
c语言开根号代码是什么
c语言怎么进行字符串比较
c语言怎么进行强制类型转换
c语言运算符的优先级顺序是什么
c++用什么软件编程
中序遍历是怎么遍历的
h文件和c文件的关系是什么