让我看看我是否理解目标。您要确保
OpponentTeam
可以随时通知
NetworkCode
从服务器接收消息。如果这是正确的,我会选择A选项。
选项A
此选项使用
delegate
和
event
.
This article
详细介绍委托、事件和处理程序方法。
代表:
// The delegate defines what method signatures can be attached to an event
public delegate void NetworkMessageReceivedHandler(string message, dynamic args);
网络代码:
class NetworkCode
{
// The multi-cast event that many instances can attach to and be notified
public event NetworkMessageReceivedHandler NetworkMessageReceived;
public void OnReceiveMessageTest()
{
// simulate the callback from the server
dynamic args = new ExpandoObject();
args.Mana = 10;
args.Path = new List<Point>
{
new Point { X = 0, Y = 0 },
new Point { X = 1, Y = 0 },
new Point { X = 1, Y = 1 }
};
// Check to see if any code has registered for this event
if (NetworkMessageReceived != null)
{
// Assuming "MOVE_OPPONENT" is a message from the server
NetworkMessageReceived("MOVE_OPPONENT", args);
}
}
}
对立面图
class OpponentTeam
{
private int mana = 0;
// The event handler for each instance
public void OnNetworkMessageReceived(string message, dynamic args)
{
switch (message)
{
case "MOVE_OPPONENT": { UpdateMana(args); } break;
// TODO: Add additional network messages here.
}
}
private void UpdateMana(dynamic args)
{
mana = args.Mana;
}
}
电线向上
NetworkCode network = new NetworkCode();
OpponentTeam opponentTeam = new OpponentTeam();
// This registers the opponent instance's handler of the network message received event
network.NetworkMessageReceived += opponentTeam.OnNetworkMessageReceived;
选项B
这个选项通过对提供的代码进行最小的更改来更直接地解决这个问题,但并没有达到我认为的目标。
我对网络代码定义进行了如下调整
class NetworkCode
{
private Dictionary<string, Tuple<OpponentTeam, MethodInfo>> registrations = new Dictionary<string, Tuple<OpponentTeam, MethodInfo>>();
public void Register(string msg, OpponentTeam team, MethodInfo method)
{
if (!registrations.ContainsKey(msg))
{
registrations[msg] = new Tuple<OpponentTeam, MethodInfo>(team, method);
}
}
public void OnReceiveMessageTest()
{
// simulate the callback from the server
dynamic args = new ExpandoObject();
args.Mana = 10;
args.Path = new List<Point>
{
new Point { X = 0, Y = 0 },
new Point { X = 1, Y = 0 },
new Point { X = 1, Y = 1 }
};
Tuple<OpponentTeam, MethodInfo> registration = registrations["MOVE_OPPONENT"];
registration.Item2.Invoke(registration.Item1, new[] { args });
}
}
...然后我这样叫它。。。
NetworkCode network = new NetworkCode();
OpponentTeam opponentTeam = new OpponentTeam();
// This gets the first method that defines the NetworkMethodAttribute
MethodInfo method = opponentTeam.GetType().GetMethods().FirstOrDefault(m => m.GetCustomAttribute<NetworkMethodAttribute>() != null);
// This gets the actual attribute for the method found
NetworkMethodAttribute attribute = method.GetCustomAttribute<NetworkMethodAttribute>();
// This calls register using the message defined by the attribute, the instance of opponent team, and the method info for invoking the method
network.Register(attribute.Message, opponentTeam, method);