簡體   English   中英

從集合中更新對象Linq's不會更新集合中的對象

[英]Updating object Linq'd from collection doesn't update the object in collection

我有兩個簡單的課程。 一個叫做UseCounter<T> ,它是其他對象的簡單容器,同時保留了有關其使用的一些信息(已經使用了多少次,以及是否可以再次使用)。

然后是Dispenser<T> ,其中包含UseConter<T>的集合,用於從集合中獲取正確的元素,然后更新其信息。

我遇到的麻煩是在Dispenser的Get()方法中。 它應返回具有CountTotalCount最低組合的對象,然后調用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;
            }
        }
    }

這就是問題:

this._elements = elements
    .Distinct()
    .Select(e => new UseCounter<T>(e));

這很懶。 每次您對_elements進行迭代時,它都會返回到原始源數據,找到一個不同的集合,然后將該集合投影到UseCounter實例的序列上。 您對這些實例所做的任何更改都與您下次遍歷_elements時發生的情況無關。

如果您對在構造中“凍結”輸入元素集感到滿意,則可以實現查詢,使其僅執行一次:

this._elements = elements
    .Distinct()
    .Select(e => new UseCounter<T>(e))
    .ToList();

現在,每次迭代elements ,都在迭代相同的引用序列。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM