有一个非常相关的问题:Create List<CustomObject> from List<string>但是它不处理同时删除重复项。
我有以下类示例:
class Widget
{
public string OwnerName;
public int SomeValue;
}
class Owner
{
public string Name;
public string OtherData;
}
我想根据小部件列表创建一个所有者列表,但只有唯一的所有者名称。
这是我尝试过的:
List<Owner> Owners = MyWidgetList.Select(w => new Owner { Name = w.OwnerName }).Distinct().ToList();
问题是结果列表中有重复项。我做错了什么?
最佳答案
你需要定义GetHashCode()
和 Equals()
为您的对象定义自定义类型的相等性。否则它会根据引用本身进行比较。
这是因为 LINQ 扩展方法使用 IEqualityComparer
比较对象的接口(interface)。如果你没有定义一个自定义比较器(你可以通过创建一个单独的类来实现 IEqualityComparer<Owner>
),它将使用默认的相等比较器,它使用类的 Equals()
和 GetHashCode()
定义。其中,如果您不覆盖它们,则会在 Equals()
上进行引用比较并返回默认的对象哈希码。
要么定义自定义IEqualityComparer<Owner>
(因为您在 Owner 序列上调用 distinct)或添加 Equals()
和 GetHashCode()
为你的类(class)。
public class Owner
{
public string Name;
public string OtherData;
public override Equals(object other)
{
if (ReferenceEquals(this, other))
return true;
if (other == null)
return false;
// whatever your definition of equality is...
return Name == other.Name && OtherData == other.OtherData;
}
public override int GetHashCode()
{
int hashCode = 0;
unchecked
{
// whatever hash code computation you want, but for example...
hashCode += 13 * Name != null ? Name.GetHashCode() : 0;
hashCode += 13 * OtherData != null ? OtherData.GetHashCode() : 0;
}
return hashCode;
}
}
完成后,您编写的查询将正常工作。
关于c# - 从 List<OtherObject> 创建 List<CustomObject>,删除重复项。,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6865153/