回调的通用存储

时间:2017-12-22 15:16:15

标签: c# .net generics

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

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方法调用时都会自动更新。

2 个答案:

答案 0 :(得分: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);
    }
}

答案 1 :(得分:1)

  1. 使用委托,因此Dictionary<Type, Delegate>已足够

        Delegate d = _callbacks[typeof(T)];
        Action<T> action = (Action < T >)d;
    
  2. 贮藏 收藏中的代表是正常的做法(不是黑客)

  3. 拳击对象是不完美的练习