回调的通用存储

问题描述 投票:2回答:2

我需要一些商店,我可以注册一些回调以自动更新。

class Store
{
    readonly Dictionary<Type, Action<dynamic>> _callbacks = new Dictionary<Type, Action<dynamic>>();

    public void Register<T>(Action<T> updateCallback)
    {
        _callbacks.Add(typeof(T), value => updateCallback(value));
    }

    public void Save<T>(T value)
    {
        _callbacks[typeof(T)](value);
    }
}

class Program
{
    private static string _stringField = "0";
    private static int _intField = 0;

    static void Main(string[] args)
    {
        var store = new Store();
        store.Register<string>(value => _stringField = value);
        store.Register<int>(value => _intField = value);
        Console.WriteLine($"{_stringField}/{_intField}");
        store.Save("5");
        Console.WriteLine($"{_stringField}/{_intField}");
        store.Save(7);
        Console.WriteLine($"{_stringField}/{_intField}");
    }
}

输出:

0/0 5/0 5/7

它工作正常。我只是不喜欢词典中的Action<dynamic>。首先它看起来像一个黑客。由于box,它在Save方法中生成dynamic操作。我知道我不能只使用泛型,因为我不是在静态环境中,但我正在寻找这个样本的最佳解决方案。请在不更改Program类的情况下告知一些代码。所以我需要注册一次,每次Save方法调用时它都会自动更新。

c# .net generics
2个回答
1
投票
  1. 使用委托,所以Dictionary<Type, Delegate>足够好 Delegate d = _callbacks[typeof(T)]; Action<T> action = (Action < T >)d;
  2. 将代表存储在集合中是正常的做法(不是黑客)
  3. 拳击对象是不完美的练习

2
投票

如果您不喜欢dynamic,可以将回调存储为Action<object>,如下所示:

class Store {
    readonly Dictionary<Type, Action<object>> _callbacks = new Dictionary<Type, Action<object>>();

    public void Register<T>(Action<T> updateCallback) {
                                                          // cast here
        _callbacks.Add(typeof(T), value => updateCallback((T) value));
    }

    public void Save<T>(T value) {
        _callbacks[typeof(T)](value);
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.