簡體   English   中英

名單 <Interface> 執行命令

[英]List<Interface> Execution Order

我有一個帶有方法的通用接口,該方法返回一個int值,例如以下(簡化的)代碼。 對我而言,重要的是應按特定順序調用它們(例如,始終需要在ClassB之前調用ClassA)。 我將如何確保此訂購始終正確。 依靠列表創建者不是最好的方法嗎?

謝謝。

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.
        }

    }
}

您可以將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

在此處輸入圖片說明

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;
}

請實現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.
        }

    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM