2012-09-06 47 views
3

我需要保持一个简短的历史记录值。所以我需要一个最大数量的项目列表。我希望它即使在满的时候也能接受新的添加。在这种情况下,我希望我添加的最古老的物品丢失。 我没有找到适合这个目的的课程,然后做了我自己的课程。我以后肯定会添加方法,但现在我有我需要的。有限项目列表

所以我的第一个问题是:它是一个正确的代码:http://pastebin.com/0BCbyNqJ 这个班对你来说看起来是否够干净?

我的第二个问题是关于这些例外,我扔。

/// <summary> 
/// Oldest item added to the list 
/// </summary> 
public T First 
{ 
    get 
    { 
     if (_head < 0) 
      throw new IndexOutOfRangeException("The list is empty"); 

     if (_firstRoundDone) 
      return _array[(_head + 1) % _max]; 
     else 
      return _array[0]; 
    } 
} 

事情之前被添加到我的清单,我想FirstLastCount调用返回null。我认为这会更有意义。但我不知道该怎么做,因为返回类型是int或T,为此我不想添加像where T:Nullable这样的约束。 由于我没有看到任何解决方案,我想知道Exception是否是最后的最优雅的方式。或者我应该实施如GetFirst(out T first)甚至TryGetFirst(out T)

+3

似乎也许一个队列会更合适? http://msdn.microsoft.com/en-us/library/7977ey2c.aspx – McGarnagle

+0

你总是可以返回'默认(T)',而不是空... – Spontifixus

+0

@dbaseman队列只是一个FIFO收集,这不是” t像LRU缓存一样具有有限的容量 – mtijn

回答

8

扩展Queue<>会产生一个很短的代码,像这样:

public class Buffer<T> : Queue<T> 
{ 
    private int? maxCapacity { get; set; } 

    public Buffer() { maxCapacity = null; } 
    public Buffer(int capacity) { maxCapacity = capacity; } 

    public void Add(T newElement) 
    { 
     if (this.Count == (maxCapacity ?? -1)) this.Dequeue(); // no limit if maxCapacity = null 
     this.Enqueue(newElement); 
    } 
} 

.Clear().ToList()将被继承,没有必要实施。

+0

我应该降级你,让我看起来很愚蠢。感谢这个聪明的解决方案。 –

+0

不客气。请注意,为了线程安全,为了获得一个线程安全的包装器,提供了一个'Synchronized'方法(MSDN具有所有信息,包括增长率:http://msdn.microsoft.com/)。 COM/EN-US /库/ system.collections.queue.aspx) – Alex

2

考虑公开可用的LRU缓存如http://code.google.com/p/csharp-lru-cache/

+0

谢谢,这看起来非常漂亮的代码。但对于我目前的小需求来说,这有点矫枉过正。正如我所描述的,我认为它会抛出一个例外情况。很有意思。 –

+0

@ Mr.Pe使用第三方代码可让您专注于应用程序的其他部分,并可在您遇到第三方代码可能已解决的其他问题时扩大规模,以帮助您。但是,它可能还有更多,它是你的决定。 – akton

+0

你说得对。但它也会带来意想不到的行为。这是一个非常小的目的,历史不超过20件。这导致我认为使用简洁而通用的解决方案会更好。 –

2

纠正我,如果我错了,但它的声音,如果你想要的是一个队列。但是,这个,is already provided in .Net。您应该可以使用它以及它提供的方法。

1

我想你需要的是一个循环缓冲区,允许溢出。这样的实现可以是found here

+0

谢谢你,这看起来非常漂亮的代码。但对于我目前的小需求来说,这有点矫枉过正。正如我所描述的,我认为它会抛出一个例外情况。很有意思。 –