列出<interface>执行顺序

时间:2017-07-03 10:07:40

标签: c# .net

我有一个带有方法的泛型接口,它返回一个int值,如下面的(简化)代码。对我来说重要的是应该以特定的顺序调用它们(例如,ClassA总是需要在ClassB之前调用)。我将如何确保此排序始终正确无误。依靠列表创建者不是最好的方法吗?

感谢。

public interface IMyInterface
{
    int DoWork();
}

public class MyClassA : IMyInterface
{
    private int _myAccumulator = 100;

    public int DoWork()
    {
        _myAccumulator -= 1;

        return _myAccumulator;
    }
}

public class MyClassB : IMyInterface
{
    private int _myAccumulator = 50;

    public int DoWork()
    {
        _myAccumulator -= 1;

        return _myAccumulator;
    }
}


public class MyWorker
{
    private List<IMyInterface> _myAccumulatorClasses = new List<IMyInterface> { new MyClassA(), new MyClassB() }

    public void CallClasses()
    {
        foreach(var accumulator in myAccumulatorClasses)
        {
            var value = accumulator.DoWork();

            if(value > 0)
                break;  // Don't call next accumulator if we get a value greater than zero back.
        }

    }
}

3 个答案:

答案 0 :(得分:5)

您可以在界面中添加Order属性:

public interface IMyInterface
{
    int DoWork();
    int Order { get; }
}

然后,在您的实施中:

public class MyClassA : IMyInterface
{
    private int _myAccumulator = 100;

    public int DoWork()
    {
        _myAccumulator -= 1;

        return _myAccumulator;
    }

    public int Order {get { return 1;} }
}

最后,迭代时OrderBy

public class MyWorker
{
    private List<IMyInterface> _myAccumulatorClasses = new List<IMyInterface> { new MyClassA(), new MyClassB() }

    public void CallClasses()
    {
        foreach(var accumulator in myAccumulatorClasses.OrderBy(x=>x.Order)))
        {
            var value = accumulator.DoWork();

            if(value > 0)
                break;  // Don't call next accumulator if we get a value greater than zero back.
        }

    }
}

这是确保订单的最安全的方式。

但是,List<>保证了插入顺序。 因此,如果按特定顺序插入,它们将按此顺序出现:

var list = new List<string>();
list.Add("1");
list.Add("2");
list.Add("3");
list.Add("4");

foreach (var element in list)
{
    Console.WriteLine(element);
}

输出:

  

1
  2
  3
  4

enter image description here

答案 1 :(得分:1)

Alex的答案很棒,但另一种方法是创建链式列表:

public interface IChainedWork
{
    int DoWork();
    IChainedWork Next { get; }
}

任何给定的IChainedWork实现都是:

public class MyClassA : IChainedWork
{
    private int _myAccumulator = 100;

    public MyClassA(IChainedWork next = null)
    {
        Next = next;
    }

    public int DoWork()
    {
        _myAccumulator -= 1;

        return _myAccumulator;
    }

    public IChainedWork Next { get; }
}

现在,处理工作将如下所示:

var current = lists.Where(l => lists.Except(new[] { l }).All(ll => ll.Next != l))
                   .FirstOrDefault(); //find the first

while (current!=null && 
       current.DoWork() <= 0)
{
    current = current.Next;
}

答案 2 :(得分:0)

请实施IComparable的CompareTo方法,如下所示:

public interface IMyInterface: IComparable
{
    int DoWork();

}

public class MyClassA : IMyInterface
{
    private int _myAccumulator = 100;

    public int CompareTo(object obj)
    {
        return this.GetType().Name.CompareTo(obj.GetType().Name);
    }

    public int DoWork()
    {
        _myAccumulator -= 1;

        return _myAccumulator;
    }
}

public class MyClassB : IMyInterface
{
    private int _myAccumulator = 50;


    public int CompareTo(object obj)
    {
        return this.GetType().Name.CompareTo(obj.GetType().Name);
    }
    public int DoWork()
    {
        _myAccumulator -= 1;

        return _myAccumulator;
    }
}


public class MyWorker
{
    private List<IMyInterface> _myAccumulatorClasses = new List<IMyInterface> { new MyClassA(), new MyClassB() };

public void CallClasses()
    {
        _myAccumulatorClasses.Sort();
        foreach (var accumulator in _myAccumulatorClasses)
        {
            var value = accumulator.DoWork();

            if (value > 0)
                break;  // Don't call next accumulator if we get a value greater than zero back.
        }

    }
}