将通用委托操作<T>转换为操作<string>



我正在为缓存使用实现pub/sub模式。下面的类假定用于发布任何类型的数据。订阅者可以在事件上附加一个ActionT的回调。但如果不让类泛型,我就不能在类级别创建泛型事件我不想这样做。因此,我尝试使用JsonSerializer将值来回转换为字符串,如下所示。

public class CacheNotification
{
public Action<string> CachePublished;
public Task Publish<T>(T value)
{
var json = JsonSerializer.Serialize(value);
OnCachePublished(json);
return Task.CompletedTask;
}
public Task Subscribe<T>(Action<T> callback)
{
Action<string> newCallback = (string json) => 
callback(JsonSerializer.Deserialize<T>(json));
CachePublished += newCallback;
return Task.CompletedTask;
}

protected virtual void OnCachePublished(string value)
{
if(CachePublished != null){
CachePublished.Invoke(value);
}
}
}

所以问题是在订阅方法上,我尝试的铸造只适用于Action字符串。ActionintActionobject

public Task Subscribe<T>(Action<T> callback)
{
Action<string> newCallback = (string json) => 
callback(JsonSerializer.Deserialize<T>(json));
CachePublished += newCallback;
return Task.CompletedTask;
}
这是我使用的一个测试。第二个订阅者 失败
Action<string> sub1Callback = msg =>
{
sub1Counter++;
};
Action<int> sub2Callback = num =>
{
sub2Counter++;
};
var sub1 = await cache.Subscribe(sub1Callback);
var sub2 = await cache.Subscribe(sub2Callback);
await cache.Publish("Value1");
Assert.Equal(1, sub1Counter);
Assert.Equal(1, sub2Counter);

你的问题在这里:

Action sub2Callback = num =>

等待cache.Publish("Value1";

你:

public Task Subscribe<T>(Action<T> callback)
{
Action<string> newCallback = (string json) => callback(JsonSerializer.Deserialize<T>(json));
CachePublished += newCallback;
return Task.CompletedTask;
}

尝试反序列化"Value1"对其进行整型并且正确失败。这是不可能的。

尝试发送整数值而不是"Value1"它应该可以工作。

另一种方法是重构您的Subscribe方法,使其独立于给定的类型,但我猜这不能按照您的意图完成。

最新更新