高级DynamicInvocation参数,用于"委托交换机"

时间:2017-03-15 14:36:44

标签: c# .net delegates

上下文

在我的空闲时间,我想开发一种能满足以下需求的工具:

  • 循环一位[]值,为每个True执行一个确定的方法。
  • 易于实现新方法,并且在新过滤器的情况下易于调用或者在bit []值中添加长度。

我称之为需要"委托交换机"但它们与switch ...

没有实际关系

需要

我意识到我也想为我的方法提供参数(这可能与方法不同)。所以我搜索了解决方案并找到了使用OperatorOnFilter的继承而没有参数的技巧。

我想知道的是:

  • 没有继承(更改OperatorOnFilter)是否存在一种方法?
  • (如果没有,可选择任何建筑推荐?)
  • (可选地,Delegate.DynamicInvoke()有点慢。有什么好主意吗?)

现有代码

public class OperatorOnFilter
{
    Dictionary<int, Delegate> Operations;
    public OperatorOnFilter() { Operations = new Dictionary<int, Delegate>(); }

    public void AddOrReplace(int numTraitement, Delegate Action)
    {
        if (Operations.ContainsKey(numTraitement))
            Operations[numTraitement] = Action;
        else
            Operations.Add(numTraitement, Action);
    }

    public void ApplyOperations(FilterManager Filter)
    {
        for (int i = 0; i < Filter.Values.Count(); i++)
            if (Operations.ContainsKey(i) && Filter.Values[i])
                Operations[i].DynamicInvoke();
    }
}

public class FilterManager
{
    public bool[] Values;
    public FilterManager(int filtre)
    {
        List<bool> tmpList = new List<bool>();
        int i = 0;
        while (filtre >> i > 0)
        {
            tmpList.Add((filtre & (1 << i)) == (1 << i));
            i++;
        }
        Values = tmpList.ToArray();
    }
}

测试

class Program
{
    static int theYes = 0;

    delegate void operate();
    static void Main(string[] args)
    {
        int i = 0;
        OperatorOnFilter myOperators = new OperatorOnFilter();
        myOperators.AddOrReplace(0, (operate)delegate() { Console.Write("a"); theYes++; }); //1
        myOperators.AddOrReplace(1, (operate)delegate() { Console.Write("b"); theYes++; }); //2
        myOperators.AddOrReplace(2, (operate)delegate() { Console.Write("c"); theYes++; }); //4

        myOperators.ApplyOperations(new FilterManager(7));      //"abc" 7 = 1 + 2 + 4
        myOperators.ApplyOperations(new FilterManager(3));     //"ab" 3 = 1 + 2
        myOperators.ApplyOperations(new FilterManager(6));    //"bc" 6 = 2 + 4

        Console.WriteLine(theYes); // 7

        Console.ReadKey();
    }

}
// FINAL RESULT :
// abcabbc
// 7

2 个答案:

答案 0 :(得分:0)

如果我理解你的问题,你正在寻找一种方法来编写函数而不指定你传入的参数数量。

使用params keyword可以做到这一点。 https://msdn.microsoft.com/en-us/library/ms228391(v=vs.90).aspx

还有一个好的(可能更好)的例子

这可能要求您至少声明要传入的参数的类型。但是,您可以将该类型设置为Object或泛型,或者甚至使用您已熟悉的Delegate类型来传入其他功能。

如果这样做,函数签名将如下: public void AddOrReplace(Delegate Action,params int [] list){...}

你会用它来称呼它: myOperators.AddOrReplace((操作)委托(){Console.Write(“a”);是的++;},1,2,3,4,5;

答案 1 :(得分:0)

基于@Erk评论和一些自我改进。我在委托和AddOrReplace方法上使用显式参数找到了我的答案。

最终代码(自从我使用.NET 3.5以来添加了元组)

class Program
{
    static int theYes = 0;

    delegate void operate1();
    delegate void operate2(string a);
    delegate void operate3(string a, uint x);
    static void Main(string[] args)
    {
        int i = 0;
        OperatorOnFilter myOperators = new OperatorOnFilter();
        myOperators.AddOrReplace(0, (operate1)delegate() { Console.Write("a"); theYes++; }); //1
        myOperators.AddOrReplace(1, (operate2)delegate(string a) { Console.Write(a); theYes++; }, "b"); //2
        myOperators.AddOrReplace(2, (operate3)delegate(string a, uint x) { for (uint j = 0U; j < x; j++) { Console.Write(a); theYes++; } }, "c", 3U); //4

        myOperators.ApplyOperations(new FilterManager(7));      //"abccc" 7 = 1 + 2 + 4
        myOperators.ApplyOperations(new FilterManager(3));     //"ab" 3 = 1 + 2
        myOperators.ApplyOperations(new FilterManager(6));    //"bccc" 6 = 2 + 4

        Console.WriteLine(theYes); // 11

        Console.ReadKey();
    }

}

测试类

{{1}}