提问人:Soner from The Ottoman Empire 提问时间:3/31/2023 最后编辑:Peter CsalaSoner from The Ottoman Empire 更新时间:3/31/2023 访问量:53
为什么我们要使用事件关键字,尽管应用程序可以在没有它的情况下工作?
Why should we use event keyword though the app works without it?
问:
我仍然难以理解使用事件关键字与不实际之间的区别。例如,如果我们删除以下示例中的关键字,则一切正常。如果它有效,我们为什么需要它?我仍然可以制作一些供订阅者消费的东西。如果有必要知道的话,我正在研究 .Net 6。event
using System;
using System.Threading;
public class Order
{
public string Item { get; set; }
public string Ingredients { get; set; }
}
public class FoodOrderingService
{
public delegate void FoodPreparedEventHandler(object source, EventArgs args);
public event FoodPreparedEventHandler FoodPrepared;
public void PrepareOrder(Order order)
{
Console.WriteLine($"Preparing your order '{order.Item}', please wait...");
Thread.Sleep(4000);
OnFoodPrepared();
}
protected virtual void OnFoodPrepared()
{
FoodPrepared?.Invoke(this, null);
}
}
public class AppService
{
public void OnFoodPrepared(object source, EventArgs eventArgs)
{
Console.WriteLine("AppService: your food is prepared.");
}
}
class Program
{
static void Main(string[] args)
{
var order = new Order { Item = "Pizza with extra cheese" };
var orderingService = new FoodOrderingService();
var appService = new AppService();
//var mailService = new MailService();
orderingService.FoodPrepared += appService.OnFoodPrepared;
//orderingService.FoodPrepared += mailService.OnFoodPrepared;
orderingService.PrepareOrder(order);
Console.ReadKey();
}
}
答:
2赞
jmcilhinney
3/31/2023
#1
如果删除该代码中的关键字,则只剩下以下内容:event
public FoodPreparedEventHandler FoodPrepared;
因此,这是一个公共字段,其行为与任何其他字段一样。是的,您仍然可以从类中调用委托,但您不仅限于此,就像处理事件一样。这是来自关键字的文档,您应该已经阅读过:event
事件是一种特殊的多播委托,只能是 从类(或派生类)或结构中调用,其中 它们被声明(Publisher 类)。如果其他类或结构 订阅事件,其事件处理程序方法将被调用 当 Publisher 类引发事件时。
如果它是一个字段,则可以从任何可以访问它的位置替换任何现有委托,也可以从外部调用这些现有委托。对于事件,您不能执行任何操作。
评论
0赞
Soner from The Ottoman Empire
3/31/2023
你是否介意用一个最小的代码示例来显示,根据你说你可以从任何可以访问它的地方替换任何现有的委托,你也可以从外部调用这些现有的委托。对于事件,您不能执行任何操作。?
1赞
jmcilhinney
3/31/2023
@SonerfromTheOttomanEmpire,为什么你需要我举例说明公共领域是如何运作的?您已经知道如何获取或设置字段。类型与此没有区别。
0赞
Soner from The Ottoman Empire
3/31/2023
因为在我看来,你太有经验的人了,即使你按一下键,我也可能会学到新东西,所以我不想错过这个机会(:
0赞
jmcilhinney
3/31/2023
@SonerfromTheOttomanEmpire,没有什么可学的。字段是字段,字段是字段。如果字段是公共的,那么您可以获取它引用的对象并使用它,无论它是什么类型。如果类型是委托,则可以获取该对象并使用它。这是一个与其他任何领域一样的领域。你知道一个领域是如何运作的。不要再试图让它比实际情况更复杂了。
0赞
Soner from The Ottoman Empire
3/31/2023
好的,先生,你怎么想。谢谢你的帮助。
1赞
Peter Csala
3/31/2023
#2
请允许我试着强调其中的一些差异。
为了简单起见,让我们有这样的代码:
public delegate void FoodPreparedEventHandler(object source, EventArgs args);
public class FoodOrderingService
{
public event FoodPreparedEventHandler FoodPreparedEvent;
public FoodPreparedEventHandler FoodPrepared;
}
var service = new FoodOrderingService();
//DOES COMPILE
service.FoodPrepared = new FoodPreparedEventHandler((_, ___) => {});
service.FoodPrepared(null, null);
//DOES NOT COMPILE
service.FoodPreparedEventHandler = new FoodPreparedEventHandler((_, ___) => {});
service.FoodPreparedEvent(null, null);
- 无法重新分配(只能使用或运算符)
event
-=
+=
- 不能在类外部调用
event
+1 在接口中,您不能定义字段,但可以定义事件
public interface IFoodOrderingService
{
event FoodPreparedEventHandler FoodPreparedEvent;
FoodPreparedEventHandler FoodPrepared; //DOES NOT COMPILE
}
评论
0赞
Soner from The Ottoman Empire
3/31/2023
谢谢。+1,然而,“覆盖”关键字有点令人困惑。相反,“重新分配”会更好。
0赞
Peter Csala
3/31/2023
@SonerfromTheOttomanEmpire True,更正:D
评论