2

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

要排队的类)

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 还是其他方式?

4

4 回答 4

4

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

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

这也符合“告诉,不要问”。

于 2013-07-02T09:27:33.627 回答
2

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

让每个对象实现一个公开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();
            }
        }
    }
}
于 2013-07-02T09:30:28.727 回答
0

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

您必须考虑如何处理已出列的项目。如果您只是将 then 存储在队列中,则为每种类型使用两个或更多队列。如果无论它们是什么类型,您都将它们用于某些事情,那么请考虑使用一个接口,该接口将实现这些类型或继承其他类型的基类。

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

于 2013-07-02T09:10:36.413 回答
0

我实际上不会说 1 或 2。

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

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

于 2013-07-02T09:10:45.287 回答