在字典中存储通用操作

Storing a generic Action in a Dictionary

T 适用于该方法,但如果不在 class 上定义 T 则不适用于 Dictionary,这是我做不到的。这可能吗?如果没有,是否有另一种方法可以像这样完成存储通用回调方法。

此 class 适用于 Websockets Json-Rpc 客户端。我正在连接的 API 允许您订阅不同的数据流。 IE。股票报价、股票交易等都有不同的领域。

我希望能传入订阅数据的名称,然后是回调,而且是param类型,数据返回后传入。

// Store list of callback to invoke once data arrives
private Dictionary<string, Action<T>> _callbacks = new Dictionary<string, Action<T>>();

// Subscribe to websocket API streaming data
public async Task SubscribeAsync<T>(string name, Action<T> callback)
{
    _callbacks.Add(name, callback);

    ... other code here ...

}

// Data is eventually received here from the websocket API
private async Task _wsClient_OnDataReceived(string jsonData)
{
    var docRoot = JsonDocument.Parse(jsonData).RootElement;
    var deserialzizedData = ...
    _callbacks[dataName].Invoke(deserialzizedData);
}

这行得通。请注意,SubscribeAsync<T> became SubscribeAsync 作为类型在第二个参数中传递:

namespace Callbacks {
    class SubMgr<T> {
        private Dictionary<string, Action<T>> _callbacks = new Dictionary<string, Action<T>>();

        public async Task SubscribeAsync(string name, Action<T> callback ) {

            _callbacks.Add(name, callback);
            _callbacks.Add(name, Method1);
            _callbacks.Add(name, Method2);

            // ... other code here...
        }

        public void Method1(T a) { }
        public void Method2(T a) { }

    }
}

问题是您试图在 Dictionary<TKey, TValue> 中存储多个潜在的多态类型。但是,字典期望其中的每个项目都具有完全相同的类型。因此,在您的情况下,每个 Action<T> 必须完全相同,这意味着 <T> 必须是所有实例的相同类型。

你可以解决这个问题,但是,如果是一个接口。例如:

private Dictionary<string, Action<IActionable>> _callbacks = new Dictionary<string, Action<IActionable>>();

其中 IActionable 是所有类型实现的一些通用接口。或者,它不是接口,而是它们都继承自的公共基础 class。

无论如何,重点是您希望 Action<T> 相同,但以多态方式处理实例。为此,您需要一个他们实现的接口或一个包含您要调用的方法的公共基础 class。您将作为接口或基 class 的实例将项目添加到字典中,并且您将通过相同的方式调用所需的方法。