C# 请帮助我以正确的方式编写此事件 原始问题
我至少读过十几篇关于事件的文章和线索,并且已经弄明白了基本的想法,但是我对如何正确地做这件事有点困惑™. 似乎至少有两种编写事件的常用方法,一种比另一种更受推荐 我看到了很多资料,作者跳过了部分过程,假设出于某种原因,你会知道这一点。还有很多教程,比如“MyEventExample”和“SomeProcessGoesher”,这使得我们很难从整体上理解这个例子。许多例子在教你如何做某件事的过程中经历了所有的麻烦,但最后只是说你在现实中当然永远不会做那件事——但它们并没有提供你做这件事的方式 最后,使用事件的场景的每个组件的命名约定似乎无处不在。我很难弄清楚某些概念在哪里被应用,因为每个人对它的每个部分都有不同的名称 这就是我想要的:我在游戏中有一个简单的情况,可以利用事件。我希望有人能进来写一篇事件连线,展示推荐的方法以及最常见的命名和结构约定。我知道要求为我编写代码的形式很糟糕,但我真的在寻找编写代码的方法,这样我就可以自信地开始为自己编写代码了 请忽略这是否是一个好的游戏设计,甚至它是否是一个事件的适当情况。我只是对如何正确编写事件内容感兴趣,这是我的示例空间C# 请帮助我以正确的方式编写此事件 原始问题,c#,events,conventions,C#,Events,Conventions,我至少读过十几篇关于事件的文章和线索,并且已经弄明白了基本的想法,但是我对如何正确地做这件事有点困惑™. 似乎至少有两种编写事件的常用方法,一种比另一种更受推荐 我看到了很多资料,作者跳过了部分过程,假设出于某种原因,你会知道这一点。还有很多教程,比如“MyEventExample”和“SomeProcessGoesher”,这使得我们很难从整体上理解这个例子。许多例子在教你如何做某件事的过程中经历了所有的麻烦,但最后只是说你在现实中当然永远不会做那件事——但它们并没有提供你做这件事的方式 最后
//In my game I have a number of entities which can 'talk' to the player.
//An NPC can greet them, a zone might 'greet' them by displaying "Cityville"
//when they enter it, their inventory might tell them they're out of space,
//and so on. Everything would pass a Message object to a Messenger object,
//which would then deliver the messages as it saw fit.
public class Messenger
{
private Queue<Message> _messages = new Queue<Message>();;
private Stack<Message> _archive = new Stack<Message>();;
public IEnumerable<Message> Messages { get { return _messages.AsEnumerable(); } }
public IEnumerable<Message> Archive { get { return _archive.AsEnumerable(); } }
public void Add(Message message)
{
_messages.Enqueue(message);
}
public void Deliver()
{
Message msg = _messages.Dequeue();
_archive.Push(msg);
//Here's where I'd broadcast to any subsystem listening
//that the message was delivered
//Event args should be (_archive.Peek(), DateTime.Now);
}
public event MessageDeliveryEvent Delivery;
protected virtual void OnDelivery(MessageHandlerDeliveryEventArgs e)
{
if (this.Delivery != null) { this.Delivery(this, e); }
}
}
//Okay, here's my delegate declared outside any class. One tutorial suggested
//putting it in the same file as the event arguments class so it would be
//easier to find, which sounds reasonable to me, but I dunno.
public delegate void MessageDeliveryEvent(object sender, MessageHandlerDeliveryEventArgs e);
//I've seen examples where they don't even write an event arguments class.
//I think you could probably just pass the same stuff directly, but the
//separate class sounds like a good idea, more flexible if things change.
public class MessageHandlerDeliveryEventArgs : EventArgs
{
private readonly Message _message;
private readonly DateTime _delivered;
public MessageHandlerDeliveryEventArgs(Message message, DateTime delivered)
{
_message = message;
_delivered = delivered;
}
public Message Message { get { return _message; } }
public DateTime DeliveryDateTime { get { return _delivered; } }
}
//So in the UI layer I'd have things like a ChatBox which would be a
//scrolling list of everything said to the player. There would also be a
//GeneralInfoBox control that displayed things like what zone you just
//entered, or that your inventory is full. Both would listen to the
//Messenger object for a delivery event, and then check the Message object
//associated with that event to see if they needed to handle the display
//of that message.
public class ChatBox
{
//OMG there's a new message, lemme see if I should display it
private void TheThingThatListensToMessengerEvents(Message message, DateTime datetime)
{
if Message.Type == MessageType.Chat { Print(datetime.ToString() + ": " + message.Text); }
}
public string Print(string text) {}
}
public class GeneralInfoBox
{
//OMG there's a new message, lemme see if I should display it
private void TheThingThatListensToMessengerEvents(Message message)
{
if Message.Type == MessageType.General { Print(message.Text); }
}
public string Print(string text) {}
}
//在我的游戏中,我有许多实体可以与玩家“对话”。
//NPC可以问候他们,区域可以通过显示“Cityville”来“问候”他们
//当他们进入时,他们的库存可能会告诉他们空间不足,
//等等。一切都会将消息对象传递给Messenger对象,
//然后,它将按照自己认为合适的方式传递信息。
公务舱信使
{
专用队列_messages=new Queue();;
私有堆栈_archive=新堆栈();;
公共IEnumerable消息{get{return_Messages.AsEnumerable();}
公共IEnumerable存档{get{return _Archive.AsEnumerable();}}
公共无效添加(消息)
{
_消息。排队(消息);
}
公共图书馆
{
Message msg=_messages.Dequeue();
_存档推送(msg);
//这是我向任何正在收听的子系统广播的地方
//消息已经传递了
//事件参数应该是(_archive.Peek(),DateTime.Now);
}
公共事件消息传递事件传递;
受保护的虚拟void OnDelivery(MessageHandlerDeliveryEventArgs e)
{
如果(this.Delivery!=null){this.Delivery(this,e);}
}
}
//好的,这是我的委托在任何类之外声明的。一个教程建议
//将它与事件参数类放在同一个文件中
//更容易找到,这听起来很合理,但我不知道。
公共委托void MessageDeliveryEvent(对象发送者,MessageHandlerDeliveryEventArgs e);
//我见过一些例子,其中他们甚至没有编写事件参数类。
//我想你可以直接传递同样的东西,但是
//单独上课听起来是个好主意,如果情况发生变化,会更加灵活。
公共类MessageHandlerDeliveryEventArgs:EventArgs
{
专用只读消息\u消息;
私有只读日期时间(已交付);
public MessageHandlerDeliveryEventArgs(消息消息、日期时间已送达)
{
_消息=消息;
_交付=交付;
}
公共消息消息{get{return_Message;}}
public DateTime DeliveryDateTime{get{return\u delivered;}
}
//因此,在UI层中,我会有一个聊天室之类的东西,它是一个
//滚动列表,列出所有对玩家说的话。还将有一个
//GeneralInfo框控件,该控件显示的内容包括
//输入,或者您的库存已满。两人都会听音乐
//用于传递事件的Messenger对象,然后检查Message对象
//与该事件关联,以查看他们是否需要处理显示
//这一信息的重要性。
公共类聊天室
{
//天哪,有新消息,让我看看是否应该显示它
private void列出的ThingThingthat事件(消息消息、日期时间、日期时间)
{
如果Message.Type==MessageType.Chat{Print(datetime.ToString()+“:”+Message.Text);}
}
公共字符串打印(字符串文本){}
}
公共类通用信息框
{
//天哪,有新消息,让我看看是否应该显示它
private void Thingthat ListentHomesenger事件(消息消息)
{
如果Message.Type==MessageType.General{Print(Message.Text);}
}
公共字符串打印(字符串文本){}
}
如果我能澄清什么,请告诉我。如果有一个非常好的教程我显然错过了,请随时告诉我。提前谢谢
我从线上取了什么 这是我的例子,里面有一些事件。也许它会帮助其他像我一样思考的人(上帝保佑他们)想象它
public class MessageHandler
{
private Queue<Message> _messages = new Queue<Message>();
private Stack<Message> _archive = new Stack<Message>();
public MessageHandler() { }
public IEnumerable<Message> Messages { get { return _messages.AsEnumerable(); } }
public IEnumerable<Message> Archive { get { return _archive.AsEnumerable(); } }
public void Add(Message message)
{
_messages.Enqueue(message);
}
public void Deliver()
{
Message msg = _messages.Dequeue();
_archive.Push(msg);
//Call the method which broadcasts the event
OnDelivery(new MessageDeliveryEventArgs(_archive.Peek(), DateTime.Now));
}
//The event
public event EventHandler<MessageDeliveryEventArgs> Delivery;
//The method which broadcasts the event
protected virtual void OnDelivery(MessageDeliveryEventArgs messageDeliveryEventArgs)
{
EventHandler<MessageDeliveryEventArgs> handler = Delivery;
if (handler != null) { handler(this, messageDeliveryEventArgs); }
}
}
//The event arguments class for the event of interest. Carries information about this kind of event
public class MessageDeliveryEventArgs : EventArgs
{
private readonly Message _message;
private readonly DateTime _delivered;
public MessageDeliveryEventArgs(Message message, DateTime delivered)
{
_message = message;
_delivered = delivered;
}
public Message Message { get { return _message; } }
public DateTime DeliveryDateTime { get { return _delivered; } }
}
//A UI control which listens for an event in a Messenger object
public class ChatBox
{
//Specify the instance of the Messenger class to whose event(s) we plan to subscribe
public ChatBox(MessageHandler messenger)
{
//Subscribe this control's OnDelivery method to the Delivery event of the specified instance of Messenger
messenger.Delivery += this.OnDelivery;
}
//The method which we intend to subscribe to the Delivery event of an instance of Messenger
private void OnDelivery(object sender, MessageDeliveryEventArgs e)
{
if (e.Message.Format == MessageFormat.Local)
{
Print(String.Format("{0}: {1}", e.DeliveryDateTime, e.Message.Text));
}
}
private void Print(string text) { }
}
公共类MessageHandler
{
专用队列_messages=新队列();
私有堆栈_archive=新堆栈();
public MessageHandler(){}
公共IEnumerable消息{get{return_Messages.AsEnumerable();}
公共IEnumerable存档{get{return _Archive.AsEnumerable();}}
公共无效添加(消息)
{
_消息。排队(消息);
}
公共图书馆
{
Message msg=_messages.Dequeue();
_存档推送(msg);
//调用广播事件的方法
OnDelivery(新的MessageDeliveryEventArgs(_archive.Peek(),DateTime.Now));
}
//事件
公共事件处理程序交付;
//广播的方法
public class ChatBox
{
public ChatBox(Messenger messenger)
{
messenger.Delivery += OnMessageDelivery;
}
private void OnMessageDelivery(object sender, MessageHandlerDeliveryEventArgs e)
{
if(e.Message.Type == MessageType.Chat)
{
Print(String.Format("{0}: {1}", e.DateTime, e.Message.Text));
}
}
}
public event EventHandler<MessageHandlerDeliveryEventArgs> Delivery;
using System;
namespace ObserverExample
{
class Program
{
static void Main(string[] args)
{
var subject = new Subject();
var observer = new Observer();
observer.Observe(subject);
subject.SomeAction();
Console.ReadLine();
}
}
public class Subject
{
public event EventHandler<TopicEventArgs> TopicHappening;
public void SomeAction()
{
OnTopicHappening(new TopicEventArgs("Hello, observers!"));
}
protected virtual void OnTopicHappening(TopicEventArgs topicEventArgs)
{
EventHandler<TopicEventArgs> handler = TopicHappening;
if (handler != null)
handler(this, topicEventArgs);
}
}
public class TopicEventArgs : EventArgs
{
public TopicEventArgs(string message)
{
Message = message;
}
public string Message { get; private set; }
}
public class Observer
{
public void Observe(Subject subject)
{
subject.TopicHappening += subject_TopicHappening;
}
void subject_TopicHappening(object sender, TopicEventArgs e)
{
Console.WriteLine(e.Message);
}
}
}