带参数的C#触发事件处理程序

问题描述 投票:0回答:1

你好,我想在我的应用程序中添加一个功能,但我就是想不通,我想传递一些参数或至少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应该存储在某个地方,他可以获取它们。

先谢谢你。

c# eventhandler
1个回答
0
投票

更新了。

谢谢你的澄清。我认为你没有完全理解事件订阅机制的工作原理。让我在例子上解释一下。我重构了一下你的代码。

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);
    }
}

这里的两个主要类是 GameAPIClient.

GameAPI 类。

  1. 追踪所有新增的玩家在私有的 players 列表。
  2. 提供一个 AddPlayer 方法,允许客户端添加玩家。
  3. 提供一个 PlayerAdded 事件来通知客户有玩家被添加。

Client 类。

  1. 订阅到 PlayerAdded 暴露的事件 GameAPI.
  2. 呼叫 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

如果这不是你所期望的,请把期望的输出结果贴出来。

© www.soinside.com 2019 - 2024. All rights reserved.