#c# #linq #intersect
#c# #linq #пересекать
Вопрос:
Я хочу пересечь 2 списка объектов, которые имеют одинаковые типы и одинаковые свойства, но объекты в списке были созданы отдельно.
class foo
{
int id;
string name;
public foo(int Id, string Name)
{
id = Id;
name = Name;
}
}
List<foo> listA = new List<foo>() {new foo(1, "A"), new foo(2, "B"), new foo(3, "C")};
List<foo> listB = new List<foo>() {new foo(2, "B"), new foo(3, "C"), new foo(4, "D")};
List<foo> intersect = listA.Intersect(listB).ToList();
foo object B amp; C находятся в listA и listB, но когда я их пересекаю, я получаю 0 записей. Я знаю это, потому что нет одного и того же объекта, но что мне нужно сделать, чтобы получить список с B и C в любом случае?. Чего мне не хватает?
Комментарии:
1. Вы не переопределяете
Equals
илиGetHashCode
. Если вы переопределите их, чтобы указать, когда вы считаете, что разные объекты равны, код будет работать без каких-либо других изменений. Или вы можете создатьIEqualityComparer<foo>
и передать этоIntersect
методу в качестве второго аргумента. (Кроме того, лучше всего сделать так, чтобы пример кода соответствовал обычным соглашениям об именовании .NET, где имена классов являются PascalCased, а имена параметров — camelCased.)2. Если они не являются одним и тем же экземпляром , что определяет, что они одинаковы ? Это
id
?3. @Martin я не уверен на 100%, достаточно ли Id, но, по крайней мере, Id должен быть равен.
Ответ №1:
Вы можете переопределить, как .NET «решает», равны ли объекты — переопределив Equals
и GetHashCode
.
Visual Studio может помочь в этом: https://learn.microsoft.com/en-us/visualstudio/ide/reference/generate-equals-gethashcode-methods?view=vs-2019
Комментарии:
1. мне удалось переопределить метод Equals, но я не уверен, как переопределить GetHashCode()
2. Помогает ли статья, на которую я ссылался в ответе? Visual Studio может автоматически сгенерировать его. Кроме того, вы можете взглянуть на другие примеры здесь: learn.microsoft.com/en-us/dotnet/api /…
Ответ №2:
Для всех, кому это нужно. Я взял ответ @arconaut и добавил его в свой код, так что теперь foo выглядит так:
class foo
{
int id;
string name;
public foo(int Id, string Name)
{
id = Id;
name = Name;
}
public override bool Equals(object obj)
{
return Equals(obj as foo);
}
public bool Equals(foo obj)
{
if (obj == null) return false;
return (id == obj.id amp;amp; name == obj.name);
}
public override int GetHashCode()
{
var hashCode = 352033288;
hashCode = hashCode * -1521134295 id.GetHashCode();
hashCode = hashCode * -1521134295 name.GetHashCode();
return hashCode;
}
}
Я все еще не уверен в хэш-коде, но он работает. итак, спасибо