8

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

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

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

4

6 回答 6

8

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

作为第一种情况的示例,如果您有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
于 2012-09-11T14:31:06.847 回答
5

您不能直接更改其中的项目Queue(尽管您可以使用Tudor 建议的解决方法)。但是如果你想有一个队列,你不必使用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);

您似乎想这样做以按顺序按几个模块处理每个项目。但我不确定这是做这种工作的正确方法。更好的方法可能是在每两个模块之间设置一个队列。一个模块总是从它的输入队列中取出一个项目,处理它,然后把它放到它的输出队列中。

这种方法的优点之一是更大的灵活性:一个模块可以在输出和输入上具有不同的类型,这对于“一个队列”方法是不可能的(除非你使用objects 的队列,或者类似的东西那)。

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

于 2012-09-11T14:50:15.463 回答
2

只要您存储的是类之类的引用类型,您对其所做的任何更改都会反映在队列中。下面代码的输出将是“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);
    }
于 2012-09-11T14:40:06.823 回答
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);
}
于 2012-09-11T14:32:39.170 回答
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);
        }
于 2012-09-11T15:19:58.610 回答
-3

简单回答是不。它不是 Queue 对象的 API 的一部分

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

然而,当然一切皆有可能。您可以编写一个扩展方法来执行此操作,但它必须与对象的 API 一起使用,因此在保留顺序的同时将所有项目与更改一起出队/入队。

但是如果你想这样做,你就是把队列当作一个列表,那么为什么不使用一个列表呢?

于 2012-09-11T14:30:39.750 回答