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();
}
}