我有两个简单的类。一个叫UseCounter<T>
,它是一个简单的容器,用于存放其他对象的简单容器,同时保存一些关于其用法的信息(已经使用了多少次,以及是否可以再次使用)。从集合更新对象Linq'd不会更新集合中的对象
然后是Dispenser<T>
,它包含UseConter<T>
的集合,用于从集合中获取正确的元素,然后更新其信息。
我遇到的麻烦是在分配器的Get()
方法中。它应返回最低组合Count
和TotalCount
的对象,然后调用Increase()
方法以增加计数。
但是,当我运行此代码时,Dispenser<T>
始终返回相同的元素。这就像Linq'd元素不是对象的引用,而是它的副本,所以Increase()
方法只增加本地对象的属性,但不增加集合中的属性。
我在这里失去,因为我从来没有遇到过这样的行为。
这里谈到的代码:
UseCounter:
public class UseCounter<T>
{
public T Element { get; private set; }
public int TotalCount { get; private set; }
public int Count { get; private set; }
public bool Useful { get; set; }
public UseCounter(T element)
{
this.Element = element;
this.Count = 0;
this.TotalCount = 0;
this.Useful = true;
}
public void IncreaseCounter()
{
this.Count++;
this.TotalCount++;
}
public void DecreaseCounter()
{
if(this.Count == 0)
{
throw new ArgumentOutOfRangeException("Count cannot be lower than 0!");
}
this.Count--;
}
}
饮水机:
private readonly object _elementLocker = new object();
private IEnumerable<UseCounter<T>> _elements;
public IEnumerable<T> Elements
{
get { return _elements.Select(e => e.Element); }
}
public int FinishedCount
{
get
{
lock (_elementLocker)
{
return _elements.Where(e => e.Useful == false).Count();
}
}
}
public int CurrentlyWorkingCount
{
get
{
lock (_elementLocker)
{
return _elements.Where(e => e.Count > 0).Count();
}
}
}
public Dispenser(IEnumerable<T> elements)
{
this._elements = elements
.Distinct()
.Select(e => new UseCounter<T>(e));
}
public T Get()
{
lock(_elementLocker)
{
var lCount = _elements
.Where(e => e.Useful == true)
.Select(e => e.Count).Min();
var lTCount = _elements
.Where(e => e.Useful == true)
.Where(e => e.Count == lCount)
.Select(e => e.TotalCount).Min();
var el = _elements
.Where(e => e.Useful == true)
.First(e => e.Count == lCount && e.TotalCount == lTCount);
el.IncreaseCounter();
return el.Element;
}
}
public void Report(T element, bool successful)
{
lock(_elementLocker)
{
var el = _elements
.First(e => e.Element == element);
el.DecreaseCounter();
if(el.Useful == true && successful == true)
{
el.Useful = false;
}
}
}