代码之家  ›  专栏  ›  技术社区  ›  Aren

使用ilist/ienumerable的奇数linq行为

  •  0
  • Aren  · 技术社区  · 15 年前

    我有以下代码:

        public IList<IProductViewModel> ChildProducts { get; set; }
        public IList<IProductViewModel> GiftItems { get; set; }
        public IList<IProductViewModel> PromoItems { get; set; }
    
        public IList<IProductViewModel> NonGiftItems
        {
            get
            {
                return NonPromoItems.Except(GiftItems, new ProductViewModelComparer()).ToList();
            }
        }
    
        public IList<IProductViewModel> NonPromoItems
        {
            get
            {
                return ChildProducts.Where(p => !p.IsPromotion).ToList();
            }
        }
    

    产品视图模型比较器:

    public class ProductViewModelComparer : IEqualityComparer<IProductViewModel>
    {
    
        #region IEqualityComparer<IProductViewModel> Members
    
        public bool Equals(IProductViewModel x, IProductViewModel y)
        {
            if (Object.ReferenceEquals(x, y))
                return true;
    
            if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null))
                return false;
    
            return String.Equals(x.ProductId, y.ProductId);
        }
    
        public int GetHashCode(IProductViewModel obj)
        {
            return obj.ProductId.GetHashCode();
        }
    
        #endregion
    }
    

    基本上, NonPromoItems (ChildProducts - PromoItems) NonGiftItems (NonPromoItems - GiftItems)

    然而,当:

    ChildProducts = IEnumerable<IProductViewModel>[6] PromoItems = IEnumerable<IProductViewModel>[1] 其中项与中的1项匹配 儿童用品 GiftItems = IEnumerable<IProductViewModel>[0]

    我的结果是

    非促销品 = IEnumerable<IProductViewModel>[5] 这是正确的 非农网 = IEnumerable<IProductViewModel>[4] 这不正确

    不知何故 Except(...) 在给定要减去的空列表时删除项。

    有什么想法吗?

    1 回复  |  直到 15 年前
        1
  •  3
  •   Judah Gabriel Himango    15 年前

    删除的项是否与列表中的另一项重复?如果是,这是except方法调用的标准行为:

    except<t>有点棘手,因为它不会像您预期的那样返回差异,而是返回 设置 差异。数学集不包含重复项(例如哈希集)。

    以下是我的一个例子:

    int[] ints = { 3, 3, 3 };
    var result = ints.Except(5); // result contains one element only: { 3 } 
    

    你可以阅读更多 this CodeProject thread 其中我描述了这个问题。

    要在保留重复项的同时获得类似“except”的功能,可以编写以下行:

    var ints = new [] { 3, 42, 3 };
    var excluded = new [] { 42 };
    var results = ints.Where(i => !excluded.Contains(i)); // returns { 3, 3 }