在字典中存储通用操作
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 的实例将项目添加到字典中,并且您将通过相同的方式调用所需的方法。
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 的实例将项目添加到字典中,并且您将通过相同的方式调用所需的方法。