是否可以更改队列中的元素?

时间:2012-09-11 14:27:35

标签: c# queue

假设我有一个整数队列(或任何类T),我可以更改队列中元素的值吗? 更具体地说,如果我将队列定义如下:

Queue<int> q = new Queue<int>();

我们可以更改其元素的值,类似于我们处理数组的方式吗? (如果q是一个数组,我们可以做这样的事情:q[0]=1来改变它的元素)。我只是想简化场景并使用int作为示例,但我的目的是试图查看队列中T类的第1项,进行一些计算并更新队列以供其他程序处理。我不想将它出列,因为队列中的序列将与原始序列不同。希望我想要做的事情有意义。请指教。

6 个答案:

答案 0 :(得分:6)

如果队列中的项目是可变类型,那么您可以更改队列具有的第一个项目的值。在不重新创建队列或执行大量队列/队列的情况下,无法更改队列前面的哪个项目。

作为第一种情况的示例,如果您的Queue<MyClass>定义为:

class MyClass
{
    public string Value { get; set; }
}

Queue<MyClass> queue = new Queue<MyClass>();
queue.Enqueue(new MyClass() { Value = "1" });
queue.Peek().Value = 2;
string value = queue.Peek().Value; // is 2

答案 1 :(得分:4)

您无法直接更改Queue中的项目(尽管您可以使用解决方法as Tudor suggested)。但是,如果您想拥有一个队列,则不必使用Queue。 .Net的另一种可能类型是LinkedList。它允许您添加和删除两端的内容,这些内容可以在您的场景中使用:

LinkedList<int> list = new LinkedList<int>();

// enqueue an item
list.AddLast(1);

// dequeue an item
var item = list.First.Value;
list.RemoveFirst();

// put item back to the front of the queue
list.AddFirst(item);

您似乎想要按顺序处理几个模块中的每个项目。但我不确定这是做这种工作的正确方法。更好的方法可能是在每两个模块之间建立一个队列。模块总是从其输入队列中获取一个项目,对其进行处理,然后将其放入其输出队列中。

这种方法的一个优点是更大的灵活性:模块在输出上可以具有与输入不同的类型,这对于“一个队列”方法是不可能的(除非你求助于{{{ 1}} s,或类似的东西)。

TPL Dataflow(.Net 4.5中的新增功能)使用此方法通过并行化提高性能。它可以做到这一点,因为如果你没有一个中央队列,每个模块可以独立于其他模块处理项目。

答案 2 :(得分:1)

您可以使用简单的包装器:

class Wrapper<T>
{
    public T Value { get; set; }
}

static void Main(string[] args)
{
    Queue<Wrapper<int>> q = new Queue<Wrapper<int>>();
    Wrapper<int> wr = new Wrapper<int> { Value = 1 };
    q.Enqueue(wr);

    Wrapper<int> wr1 = q.Peek();
    wr1.Value = 2;

    int value = q.Dequeue().Value;
    Console.WriteLine(value);
}

答案 3 :(得分:1)

只要您像类一样存储引用类型,您对其所做的任何更改都将反映在队列中。下面代码的输出将为“2”:

    public class MyClass
    {
        public int Value { get; set; }
    }

    static void Main(string[] args)
    {
        Queue<MyClass> q = new Queue<MyClass>();
        q.Enqueue(new MyClass { Value = 1 });
        var i = q.Peek();
        i.Value++;
        i = q.Peek();
        Console.WriteLine(i.Value);
    }

答案 4 :(得分:1)

    public static class Extensions
    {
        public static Queue<T> SetFirstTo<T>(this Queue<T> q, T value)
        {
            T[] array = q.ToArray();
            array[0] = value;
            return new Queue<T>(array);
        }
    }

严格来说,这不会改变队列,因此需要重新分配。

        [TestMethod]
        public void Queue()
        {
            var queue = new Queue<int>(new[]{1,2,3,4});
            queue = queue.SetFirstTo(9);
            Assert.AreEqual(queue.Peek(),9);
        }

答案 5 :(得分:-3)

简单的答案是否定的。它不是Queue对象API的一部分

http://msdn.microsoft.com/en-us/library/system.collections.queue.aspx

当然,任何事情都是可能的。您可以编写一个扩展方法来执行此操作,但它必须使用对象的API,因此在保留顺序的同时将所有项目与变更一起出列/排队。

但是如果你想这样做,你将队列视为列表,那么为什么不使用List呢?