2015-10-08 2 views
2

Я пытаюсь удалить дубликаты из списка, содержащего общий класс. Общий класс выглядит следующим образом (раздел назад, например):Удалить дубликаты из списка, содержащего общий класс

public class Point2D<T> 
{ 
    public T x; 
    public T y; 

    public Point2D(T x, T y) 
    { 
     this.x = x; 
     this.y = y; 
    } 
} 

и я создал список, как это:

List<Point2D<int>> pointList = new List<Point2D<int>>(); 
pointList.Add(new Point2D<int>(1,1)); 
pointList.Add(new Point2D<int>(1,2)); 
pointList.Add(new Point2D<int>(1,1)); 
pointList.Add(new Point2D<int>(1,3)); 

Я попытался удалить дубликаты по:

pointList = pointList.Distinct().ToList(); 

ожидая, что pointList будет содержать только: (1,1), (1,2), (1,3), но он все еще содержит все четыре точки, которые были введены. Я подозреваю, что мне нужен мой собственный метод equals или comparator в Point2D, но я не знаю, так ли это, или как они должны быть написаны (если, конечно, я просто пропустил что-то простое).

ответ

4

Чтобы сделать это, необходимо переопределить метод Equals:

public class Point2D<T> 
    { 
     public readonly T x; 
     public readonly T y; 

     public Point2D(T x, T y) 
     { 
      this.x = x; 
      this.y = y; 
     } 
     public override bool Equals(object obj) 
     { 
      if (ReferenceEquals(null, obj)) return false; 
      if (ReferenceEquals(this, obj)) return true; 
      if (obj.GetType() != this.GetType()) return false; 
      return Equals((Point2D<T>) obj); 
     } 

     protected bool Equals(Point2D<T> other) 
     { 
      return EqualityComparer<T>.Default.Equals(x, other.x) && EqualityComparer<T>.Default.Equals(y, other.y); 
     } 

     public override int GetHashCode() 
     { 
      unchecked 
      { 
       return (EqualityComparer<T>.Default.GetHashCode(x)*397)^EqualityComparer<T>.Default.GetHashCode(y); 
      } 
     } 
    } 

Кроме того, вам нужно переопределить GetHashCode. Но чтобы сделать это правильно, вы должны сделать ваши x и y только для чтения полей

+0

Хороший оль-регарпер, а? – Blorgbeard

+0

@Blorgbeard да, он делает такие тиги быстрыми и легкими – Backs

+0

@ Загружает Я не уверен в методе GetHashCode, поэтому вам нужно будет прочитать об этом, но это позволяет моим модульным тестам проходить. Благодарю. – Ayb4btu

-1

Я хотел бы предложить перекрывая == оператора. This должен помочь.

+1

Это не дает ответа на вопрос. Чтобы критиковать или просить разъяснения у автора, оставьте комментарий ниже их сообщения. – Bruce

+0

@Bruce спасибо, я обязательно буду делать это с этого момента. – ChaiNunes

3

Вы можете использовать анонимный объект. Как бы это ни изменило ссылки. поэтому используйте его только тогда, когда вам не нужны предыдущие ссылки.

pointList = pointList.Select(x => new {x.x,x.y}).Distinct().Select(x => new Point2D<int>(x.x, x.y)).ToList(); 
+0

Что делает 'new {x.x, x.y}'? Что это за тип? – Ayb4btu

+0

@ Ayb4btu пользовательский тип времени компиляции, который имеет свойства только для чтения. имя и тип 'new {x.x, x.y}' генерируются компилятором во время компиляции. подробнее об анонимном объекте https://msdn.microsoft.com/en-us/library/bb397696.aspx –

Смежные вопросы