对不同类型的类实例进行排队

本文关键字:排队 实例 同类型 | 更新日期: 2023-09-27 18:20:51

我想将两种类型的类实例排入队列。例如,

排队的班级)

class A{
    int a1;
    int a2;
}
class B{
    string b1;
    string b2;
}

样品1)

ConcurrentQueue<Object> queue = ConcurrentQueue<Object>();
queue.Enqueue(new A());
queue.Enqueue(new B());
Object item;
while (queue.TryDequeue(out item))
{
    A a = item as A;
    B b = item as B;
    if(a != null){
    }
    else if(b != null){
    }
}

样品2)

class AorB{
    public A a = null;
    public B b = null;
    public AorB(A a){ this.a = a; }
    public AorB(B b){ this.b = b; }
}
ConcurrentQueue<AorB> queue = new ConcurrentQueue<AorB>();
queue.Enqueue(new AorB(new A()));
queue.Enqueue(new AorB(new B()));
AorB item;
while (queue.TryDequeue(out item))
{
    if(item.a != null){
    }
    else if(item.b != null){
    }
}

Sample1、Sample2和其他哪种方法更好?

对不同类型的类实例进行排队

它们实际上都不是一个好的实现。如果(正如您在评论中提到的)它们用于打印或蜂鸣等命令,并且它们的成员不同,那么您应该考虑它们在做什么。一个更好的方法是将他们正在做的事情提取到这样的界面中

public interface ICommand
{
    void Execute();
}

然后让A和B实现ICommand,这样他们的打印和哔哔声就由A和B处理了。这样,你的调用代码就会变成这样:

ConcurrentQueue<ICommand> queue = ConcurrentQueue<ICommand>();
queue.Enqueue(new A());
queue.Enqueue(new B());
Object item;
while (queue.TryDequeue(out item))
{
    item.execute();
}

这也符合"告诉,不要问"。

这是应用命令模式的完美情况。

让每个对象实现一个公开Execute方法的公共接口。然后让对象通过任何必要的方式来执行命令。通过将命令的执行封装到对象本身中,这使得代码更干净、更可扩展。

这是记事本代码,因此可能存在语法上的小错误。

namespace
{
    public interface ICommand
    {
        public void Execute();
    }
    public class CommandA : ICommand
    {
        public int value;
        public void Execute()
        {
            // Do something here
        }
    }
    public class CommandB : ICommand
    {
        public string value;
        public void Execute()
        {
            // Do something here
        }
    }
    public class Program
    {
        private Queue<ICommand> commands = new Queue<ICommand>();
        public Program()
        {
            this.commands.Enqueue(new CommandA());
            this.commands.Enqueue(new CommandB());
            // Much later
            while (item = this.commands.Dequeue())
            {
                item.Execute();
            }
        }
    }
}

好吧,他们都没有。如果您需要将另一个类的实例(比如C)排入队列,那么您的if语句将变得可维护。

您必须考虑如何处理退出队列的项目。若您只是存储在队列中,那个么为每种类型使用两个或多个队列。如果不管它们是什么类型,都要使用它们,那么考虑使用一个接口来实现类型或继承其他类型的基类。

由于您还没有为此提供用例,所以我的建议是抽象的。

我实际上既不说1也不说2。

如果A和B共享一个公共接口,为什么不使用任何继承呢?否则只有两个队列,如果它们没有任何公共接口,每种对象都有一个队列。

如果它们没有任何共同点,也许你不应该有一段代码来同时使用它们。两个线程,每个类型一个可能看起来不错,这取决于用例。