c# - 使用未知类型参数 (Action<any>) 调用 Action

标签 c#

我正在创建一个 API,我的目标是公开一个可以像这样调用的方法:

Library.AddCallback<string>(Type.ChatMessage, GotMessage);

private void GotMessage(string message) {
    //...
}
//or
Library.AddCallback<int>(Type.Number, GotNumber);

private void GotNumber(int number) {
    //...
}

类型<int> , <string>可以是任何类型。

在库中,方法看起来像这样:

public void AddCallback<T1>(object type, Action<T1> callback) {
    //...
}

问题是我不知何故想先将回调保存在方法调用之外(在列表中),然后再调用它。

理想情况下,我想做的是首先将其转换为一个对象,以便能够将其存储在 List<object> 中。然后将其投回 Action<T1> .然而,似乎不可能将 T1 保存到变量中(除非执行 typeof(T1),这拒绝我使用它来将其强制转换回)。

我想如何调用它的示例(我从列表中得到了 typedata):

((Action<type>)callback)(data)

最佳答案

我不确定如何 data被键入。假设它的类型是 object现在,您可以分解 Action<T>Action<object>并在其中进行转换:

private List<Action<object>> Callbacks = new List<Action<object>>();

public void AddCallback<T1>(object type, Action<T1> callback) 
{
    Callbacks.Add((data) => callback((T1)data));
}

public void FireCallback(object data)
{
    Action<object> callback = GetCallback();
    callback(data);
}

编辑:您已经将其标记为答案,但这是另一个将回调存储在类型集中的实现。

A CallbackHandler存储类型化的回调列表:

public class CallbackHandler<T> : ICallbackHandler
{
    private List<Action<T>> Callbacks = new List<Action<T>>();

    public void AddCallback<T>(Action<T> callback)
    {
        Callbacks.Add(callback);
    }

    public void Callback(object data)
    {
        T typedData = (T)data;
        foreach(var callback in Callbacks)
            callback(typedData);
    }
}

public interface ICallbackHandler
{
    void Callback(object data);
}

然后你的上级Library有这样的东西:

private Dictionary<Type, ICallbackHandler> AllCallbacks = new Dictionary<Type, ICallbackHandler>();

public void AddCallback<T>(Action<T> callback) 
{
    Type type = typeof(T);
    ICallbackHandler handler;
    if (!AllCallbacks.TryGetValue(type, out handler))
    {
        handler = new CallbackHandler<T>();
        AllCallbacks[type] = handler;
    }
    CallbackHandler<T> typedHandler = (CallbackHandler<T>)handler;
    typedHandler.AddCallback(callback);
}

public void FireCallback(object data)
{
    Type type = data.GetType();
    ICallbackHandler handler;
    AllCallbacks.TryGetValue(type, out handler);
    if (handler != null)
        handler.Callback(data);
}

这是假设 data 的类型确定触发哪个回调。如果你需要在上面再放一层(基于 Type.ChatMessageType.Number )应该不会太难。

关于c# - 使用未知类型参数 (Action<any>) 调用 Action,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16854956/

相关文章:

c# - 在 WPF 中的 DataContext 上实现 INotifyPropertyChanged?

c# - Xamarin Android应用程序未达到断点

c# - 等待最后的方法行

c# - C# 中哪个三元运算符最受欢迎且使用最多?

c# - 如果我在整个应用程序生命周期中需要 StreamWriter,在哪里处理它?

c# - XAML 多重绑定(bind) StringFormat

c# - 在 C# 中创建 RTF 文件的正确方法是什么?

c# - 如何在不更改签名的情况下将同步方法转换为异步方法

c# - 如何使 C# Switch 语句使用 IgnoreCase

c# - 使用 ArraySegment 类到 JSON 对象