你好,我想在我的应用程序中添加一个功能,但我就是想不通,我想传递一些参数或至少1个参数到使用subscriber的EventHandler。
该参数将允许我做一些检查,然后触发基于该参数的事件。
public class Client
{
public Client()
{
GameAPI api = new GameAPI();
api.AddedPlayerEvent += Api_ClarkAdded;
api.Do();
}
private void Api_ClarkAdded(object sender, GameAPI.AddedPlayerEvents e)
{
Console.WriteLine("User Clark found");
}
}
public class GameAPI
{
public event EventHandler<AddedPlayerEvents> AddedPlayerEvent;
List<AddedPlayerEvents> AddedPlayers = new List<AddedPlayerEvents>();
public GameAPI()
{
// some code to simulate generating some data
AddedPlayers.Add(new AddedPlayerEvents("Player1","James"));
AddedPlayers.Add(new AddedPlayerEvents("Player2", "Clark"));
AddedPlayers.Add(new AddedPlayerEvents("Player3", "Steve"));
}
public void Do()
{
// simulating code ...
//trigger event
if (AddedPlayers.Any(f => f.Name == "Clark")) /*value Clark should come from client using subsciber or something else*/
{
OnPlayerAdded(AddedPlayers.First(f => f.Name == "Clark"));
}
}
protected virtual void OnPlayerAdded(AddedPlayerEvents e)
{
EventHandler<AddedPlayerEvents> handler = AddedPlayerEvent;
if (handler != null)
{
handler(this, e);
}
}
public class AddedPlayerEvents
{
public string Pseudo { get; set; }
public string Name { get; set; }
public AddedPlayerEvents(string pseudo, string name)
{
Pseudo = pseudo;
Name = name;
}
}
}
这是一个简化版的我想做的事情,所以我尽量让它简单,所以你可以处理它,而不是garbadge的东西。
我已经做了一个搜索,但所有我能找到的是参数只在客户端的Methode处理程序中可见,而不是传输到EventHandler,我认为T应该存储在某个地方,他可以获取它们。
先谢谢你。
更新了。
谢谢你的澄清。我认为你没有完全理解事件订阅机制的工作原理。让我在例子上解释一下。我重构了一下你的代码。
using System;
using System.Collections.Generic;
class Program
{
static void Main(string[] args)
{
Client client = new Client();
}
}
public class Client
{
public Client()
{
GameAPI api = new GameAPI();
api.PlayerAdded += Api_PlayerAdded;
api.AddPlayer(new Player("Player2", "Clark"));
}
private void Api_PlayerAdded(object sender, PlayerAddedEventArgs e)
{
Console.WriteLine($"API PlayerAdded event has triggered. Arguments: e.Player.Name = {e.Player.Name}, e.Player.Pseudo = {e.Player.Pseudo}");
}
}
public class PlayerAddedEventArgs: EventArgs
{
public PlayerAddedEventArgs(Player player)
{
Player = player;
}
public Player Player { get; }
}
public class Player
{
public Player(string pseudo, string name)
{
Pseudo = pseudo;
Name = name;
}
public string Pseudo { get; }
public string Name { get; }
}
public class GameAPI
{
private List<Player> players = new List<Player>();
public event EventHandler<PlayerAddedEventArgs> PlayerAdded;
public void AddPlayer(Player player)
{
players.Add(player);
OnPlayerAdded(new PlayerAddedEventArgs(player));
}
protected virtual void OnPlayerAdded(PlayerAddedEventArgs e)
{
PlayerAdded?.Invoke(this, e);
}
}
这里的两个主要类是 GameAPI
和 Client
.
GameAPI
类。
players
列表。AddPlayer
方法,允许客户端添加玩家。PlayerAdded
事件来通知客户有玩家被添加。Client
类。
PlayerAdded
暴露的事件 GameAPI
.AddPlayer
方法来添加新的播放器。AddPlayer
方法将播放器添加到内部的 players
名单和电话 OnPlayerAdded
通知所有订阅的客户端关于新玩家的信息。这个通知会导致 Api_PlayerAdded
方法的所有订阅实例中的 Client
类被调用。新增的播放器将以 Player
中的财产 e
传递给本方法的参数。
原答案。
我看不出你的代码有什么问题。我修改了 Api_JamesAdded
方法,以确保其正常工作,所以完整的代码看起来像这样。
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static void Main(string[] args)
{
Client client = new Client();
}
}
public class Client
{
public Client()
{
GameAPI api = new GameAPI();
api.AddedPlayerEvent += Api_JamesAdded;
api.Do();
}
private void Api_JamesAdded(object sender, GameAPI.AddedPlayerEvents e)
{
Console.WriteLine($"Name: {e.Name}, Pseudo: {e.Pseudo}");
}
}
public class GameAPI
{
public event EventHandler<AddedPlayerEvents> AddedPlayerEvent;
List<AddedPlayerEvents> AddedPlayers = new List<AddedPlayerEvents>();
public GameAPI()
{
// some code to simulate generating some data
AddedPlayers.Add(new AddedPlayerEvents("Player1", "James"));
OnPlayerAdded(AddedPlayers.First(f => f.Pseudo == "Player1"));
AddedPlayers.Add(new AddedPlayerEvents("Player2", "Clark"));
OnPlayerAdded(AddedPlayers.First(f => f.Pseudo == "Player2"));
AddedPlayers.Add(new AddedPlayerEvents("Player3", "Steve"));
OnPlayerAdded(AddedPlayers.First(f => f.Pseudo == "Player3"));
}
public void Do()
{
// simulating code ...
//trigger event
if (AddedPlayers.Any(f => f.Name == "Clark")) /*value Clark should come from client using subsciber or something else*/
{
OnPlayerAdded(AddedPlayers.First(f => f.Name == "Clark"));
}
}
protected virtual void OnPlayerAdded(AddedPlayerEvents e)
{
EventHandler<AddedPlayerEvents> handler = AddedPlayerEvent;
if (handler != null)
{
handler(this, e);
}
}
public class AddedPlayerEvents
{
public string Pseudo { get; set; }
public string Name { get; set; }
public AddedPlayerEvents(string pseudo, string name)
{
Pseudo = pseudo;
Name = name;
}
}
}
这段代码打印出来了
Name: Clark, Pseudo: Player2
如果这不是你所期望的,请把期望的输出结果贴出来。