说我有这样的课程:
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#的创作者会这样做? (这有时会使事件变得非常困难。我想有一个很好的理由,这可能是我自己拯救了我,但我想知道它。)
答案 0 :(得分:5)
这很复杂:)
您正在使用的内容称为字段式事件。当您在班级中声明其中一个时,您正在创建一个字段和一个事件。当您“调用事件”时,您实际上正在调用该字段引用的委托。由于它是一个私有字段,您可以在类(以及任何嵌套类型)中访问它,但不能在外部访问它。
仅C#中的事件本身支持添加和删除操作。从外部,呼叫者只能订阅一个事件并取消订阅。他们不能提出它,或者找不到任何关于谁订阅的信息。当然,该类可以提供一个引发事件的方法,但是另一个类无法访问事件的后备字段
我在article about events and delegates中更详细地写了这篇文章。
答案 1 :(得分:2)
事实上,Closed(this, e);
只是在私人委托上调用invoke
。这就是为什么只有课程可以调用它。
C#隐藏了您的所有复杂性,它为您创建了一个类型事件的私有委托(您可以使用ILDASM来查看所有这些)。
私有,因此甚至不受保护。这就是为什么建议使用受保护的方法来引发事件,以便子类可以访问事件。
答案 2 :(得分:1)
那么,实际上是只允许在课堂内允许的事件?这是限制吗?
是
如果是这样,它周围有吗?
仅限FauxIdentityForm类的同意(帮助)。它可以有一个公共的OnClosed()方法 事件很像属性,其主要目的之一是封装,这就是您遇到的问题。