C#自定义列表基于属性复制值

C#自定义列表基于属性复制值,c#,C#,我有一个自定义列表类,比如说 public class Fruit { public string Name { get; set; } public string Size { get; set; } public string Weight{ get; set; } } 现在我像这样给它添加记录 List<Fruit> Fruits= new List<Fruit>(); //some foreach loop Fruit frui

我有一个自定义列表类,比如说

public class Fruit
{
    public string Name { get; set; }
    public string Size { get; set; }
    public string Weight{ get; set; }
}
现在我像这样给它添加记录

 List<Fruit> Fruits= new List<Fruit>();

 //some foreach loop 
 Fruit fruit = new Fruit();
 fruit.Name = ...;
 fruit.Size = ...;
 fruit.Weight = ...;

 Fruits.Add(fruit);
List水果=新列表();
//一些foreach循环
水果=新水果();
水果名=。。。;
水果。大小=。。。;
水果。重量=。。。;
水果。添加(水果);
我想要什么?

我想更改
公共水果类
,检查自定义列表中的任何水果是否已经具有相同的重量,然后忽略它并继续,例如,不要将其添加到列表中

我更喜欢在不更改foreach循环逻辑的情况下执行此操作。使用LINQ
。Any()
-确定序列的任何元素是否存在或是否满足条件。(MSDN:)


如果不允许重复重量,我将使用带有自定义
IEqualityComparer

public class FruitWeightComparer : IEqualityComparer<Fruit>
{
    public bool Equals(Fruit x, Fruit y)
    {
        if(x == null || y== null) return false;
        if (Object.ReferenceEquals(x, y)) return true;
        return x.Weight == y.Weight;
    }

    public int GetHashCode(Fruit obj)
    {
        return obj.Weight == null ? 0 : obj.Weight.GetHashCode();
    }
}

如果可以添加项目,则返回true。

您可以在插入时通过不插入现有水果来控制它

if (!myFruits.Any(f => f.Weight == newFruit.Weight))
   myFruits.Add(newFruit);
如果您无法操作插入逻辑,则可以创建一个自定义列表,该列表包装一个正常的
列表
,并更改
添加
的行为,如上例所示:

public class FruitsWithDistinctWeightList : IEnumerable<Fruit>
{  
    private List<Fruit> internalList;

    ... // Constructor etc.

    public void Add(Fruit fruit)
    {
       if (!internalList.Any(f => f.Weight == fruit.Weight))
         internalList.Add(fruit);
    }       

    ... // Further impl of IEnumerable<Fruit> or IList<Fruit>
}
public类水果与distinctweightlist:IEnumerable
{  
私人名单;
…//构造函数等。
公共空间添加(水果)
{
如果(!internalList.Any(f=>f.Weight==果重))
添加(水果);
}       
…//IEnumerable或IList的进一步实现
}
您还可以使用一些不允许重复项的现有集合。例如,一些基于哈希的集合,如
哈希集

var fruitsWithDistinctWeight=newhashset(new fruitweightcomarer());
你可以使用比较器,上面写着重量相等的水果是相等的:

public class FruitWeightComparer : IEqualityComparer<Fruit>
{
   public bool Equals(Fruit one, Fruit two)
   {
        return one.Weight == two.Weight;
   }

   public int GetHashCode(Fruit item)
   {
        return one.Weight.GetHashCode();
   }
}
公共类水果权重比较器:IEqualityComparer
{
公共布尔等于(水果一,水果二)
{
返回1.Weight==2.Weight;
}
公共整数GetHashCode(水果项)
{
返回一个.Weight.GetHashCode();
}
}

请注意,
HashSet
不像列表那样排序。注意,为了简单起见,上面的所有代码都假定设置了Weight字段。如果您的类中有公共setter(也就是说,不保证这一点),您必须进行适当的更改。

“不允许更改foreach循环逻辑”,那么您可以使用什么?您应该使用一个传入了自定义
IEqualityComparer
的集合。@PatrykĆwiek,尽管我认为这会起作用,我确实认为在这种情况下,它会破坏
IEqualityComparer
接口的语义。您的“自定义列表”是什么?列表在哪里使用?您可以使用List.Any进行检查,然后继续循环。使用LINQ或更简单的方法,使用某种字典,将权重作为键。
public class FruitsWithDistinctWeightList : IEnumerable<Fruit>
{  
    private List<Fruit> internalList;

    ... // Constructor etc.

    public void Add(Fruit fruit)
    {
       if (!internalList.Any(f => f.Weight == fruit.Weight))
         internalList.Add(fruit);
    }       

    ... // Further impl of IEnumerable<Fruit> or IList<Fruit>
}
var fruitsWithDistinctWeight = new HashSet<Fruit>(new FruitWeightComparer());
public class FruitWeightComparer : IEqualityComparer<Fruit>
{
   public bool Equals(Fruit one, Fruit two)
   {
        return one.Weight == two.Weight;
   }

   public int GetHashCode(Fruit item)
   {
        return one.Weight.GetHashCode();
   }
}