Сравните два объекта с одинаковыми данными - PullRequest
1 голос
/ 24 марта 2009

Я хочу сравнить два объекта, например:

 DirectoryInfo di1 = new DirectoryInfo("C:\\");
 DirectoryInfo di2 = new DirectoryInfo("C:\\");

ОК, да, я знаю, что у нас есть другая ссылка, этот класс не реализует IComparable, и даже GetHashCode возвращает разные результаты.

Но они одинаковы! (Логически:))

Я знаю, что могу использовать отражение, чтобы сравнить каждое поле и свойство между классами, но это слишком медленно.

Я также могу использовать сериализацию; сериализуйте каждый объект и сравните двоичные данные, но это еще медленнее!

Любые другие идеи ??

Ответы [ 8 ]

5 голосов
/ 24 марта 2009

Я бы рекомендовал создать реализацию IEqualityComparer<DirectoryInfo> и инкапсулировать там код проверки на равенство. Вот ссылка на документацию по IEqualityComparer<T>:

http://msdn.microsoft.com/en-us/library/ms132151.aspx

4 голосов
/ 24 марта 2009

Что не так с di1.FullPath == di2.FullPath?

Если полные пути совпадают, вы можете определить, что это один и тот же каталог, даже если свойства экземпляра различаются. В большинстве случаев более глубокое сравнение представляется бессмысленным.

2 голосов
/ 24 марта 2009

Напишите функцию, которая выполняет сравнение. Например, учитывая этот тип:

class Foo
{
    public int Bar;
}

Напишите такую ​​функцию:

static Boolean areEqual(Foo first, Foo second)
{
    return first.Bar == second.Bar;
}

Редактировать

Вот как вы могли бы сделать это как метод расширения:

static class Extensions
{
    public static Boolean Equals(this Foo source, Foo foo)
    {
        return first.Bar == second.Bar;
    }
}

Что позволит вам сделать это:

Foo first = new Foo();
Foo second = new Foo();
Boolean areEqual = first.Equals(second);
1 голос
/ 24 марта 2009

Да, в идеале GetHashCode () должен возвращать одно и то же значение для одних и тех же данных, но в платформе .NET существует множество классов, которые полагаются на поведение по умолчанию с разными значениями для разных ссылок.

При этом GetHashCode (), возвращающий одно и то же значение, НЕ должен использоваться в качестве индикатора равенства ни для одного класса. Эта функция предназначена для помощи в хранении в памяти хеш-таблиц (и аналогичных) структур, где используется функция приблизительного равенства или близкого значения.

В вашем случае ваш единственный реальный вариант - написать свой. Если это для использования в чем-то вроде IDictionary, то вам нужно просто создать конкретный класс, который реализует интерфейс IEqualityComparer.

Короче говоря, не существует общего универсального метода определения равенства данных для ссылочного типа, поскольку значение может (и будет) изменяться для различных типов.

0 голосов
/ 25 марта 2009

Что вы на самом деле хотите сравнить?

  1. Пути
  2. Количество файлов в каждом каталоге и их пути
  3. Все пути дочерних файлов
  4. Все дочерние файлы и все их атрибуты (это много сравнений)
  5. Все дочерние каталоги
  6. Все дочерние файлы и все их атрибуты (то же самое до 3)
  7. Все вышеперечисленное

Как только вы поняли это, вы можете написать сравнение в хэш-коде или IComparable, IComparer, Equals, Equatable и т. Д.

Путь к Windows - это то, что я лично проверяю, используя хеш-код строки. У вас не может быть "C: \ blah" и "C: \ Blah", однако вы можете использовать операционные системы на основе Unix (или C: \ будет / или ~ /).

Так что проверка двух путей на мой взгляд, хорошо. Так же, как пишет Майкл Медоус.

0 голосов
/ 24 марта 2009

Я думаю, что отражение - это единственное, что сработает. Вы можете оптимизировать его, используя код gen или даже выражения LINQ.

0 голосов
/ 24 марта 2009

Вы хотите сравнить пути DirectoryInfo? Используйте .ToString () и сравните пути в строковом формате.

0 голосов
/ 24 марта 2009

Это смысл интерфейса IEquatable, который является строго типизированной версией метода "старый как холмы" object.Equals(). (или, возможно, IComparable, но вы упомянули, что это не реализуется.)

Если вы производили свой собственный объект с разумным значением «равенство», которое не означает «та же ссылка», то вам следует реализовать IEquatable и / или переопределить object.Equals(). Учитывая, что вы используете объект без этого, вам нужно будет создать функцию для сравнения их соответствующих свойств любым удобным для вас способом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...