什么控制可以调用事件的位置?

时间:2010-11-29 22:20:16

标签: c# events

说我有这样的课程:

public class FauxIdentityForm
{
    public Guid FormID { get; set; }
    public event EventHandler Closed;
    public void TheObjectWasClosed(EventArgs e)
    {
        Closed(this, e);
    }
}

我可以在TheObjectWasClosed方法中调用Closed事件。但是,如果在不同的类中(即使在同一个文件中),我有一个这样的方法:

public void CallTheEvent()
{
    FauxIdentityForm _formIdentity = new FauxIdentityForm {FormID = Guid.NewGuid()};

    _formIdentity.Closed(_formIdentity, null);  // <-- Does not compile!
}

对Closed的调用被编译器击落(它希望我只使用+ =和 - =)。

那么,实际上是只允许在课堂内允许的事件?这是限制吗?

如果是这样,它周围有吗?如果没有,为什么C#的创作者会这样做? (这有时会使事件变得非常困难。我想有一个很好的理由,这可能是我自己拯救了我,但我想知道它。)

3 个答案:

答案 0 :(得分:5)

这很复杂:)

您正在使用的内容称为字段式事件。当您在班级中声明其中一个时,您正在创建一个字段一个事件。当您“调用事件”时,您实际上正在调用该字段引用的委托。由于它是一个私有字段,您可以在类(以及任何嵌套类型)中访问它,但不能在外部访问它。

仅C#中的事件本身支持添加和删除操作。从外部,呼叫者只能订阅一个事件并取消订阅。他们不能提出它,或者找不到任何关于谁订阅的信息。当然,该类可以提供一个引发事件的方法,但是另一个类无法访问事件的后备字段

我在article about events and delegates中更详细地写了这篇文章。

答案 1 :(得分:2)

事实上,Closed(this, e);只是在私人委托上调用invoke。这就是为什么只有课程可以调用它。

C#隐藏了您的所有复杂性,它为您创建了一个类型事件的私有委托(您可以使用ILDASM来查看所有这些)。

私有,因此甚至不受保护。这就是为什么建议使用受保护的方法来引发事件,以便子类可以访问事件。

答案 2 :(得分:1)

  

那么,实际上是只允许在课堂内允许的事件?这是限制吗?

  

如果是这样,它周围有吗?

仅限FauxIdentityForm类的同意(帮助)。它可以有一个公共的OnClosed()方法 事件很像属性,其主要目的之一是封装,这就是您遇到的问题。