2011-12-19 5 views
1

Во-первых, я скажу, что я хочу сравнить: My Custom Object (Item) имеет список строк taxids. . Я хочу посмотреть, если все строки в одном списке встречаются в другом списке строк (будет еще один taxids другого объекта (п)Сравнение двух пользовательских объектов (с использованием IEqualityComparer)

Таким образом, это класс:

public class Item 
{ 
    public long taxid { get; set; } 
    public long contentid { get; set; } 
    public string taxname { get; set; } 
    public IEnumerable<string> taxids { get; set; } 
} 

Затем эти являются фиктивными пользовательские объекты:

List<string> numbers = new List<string> { "5", "1" }; 
    List<string> numbers2 = new List<string> { "1", "2", "5","3","564" }; 

    Item pr = new Item(); 
    pr.contentid = 2517; 
    pr.taxid = 2246; 
    pr.taxids = numbers.AsEnumerable(); 
    pr.taxname = "nameItem1"; 
    List<Item> te = new List<Item>(); 
    te.Add(pr); 
    IQueryable<Item> er = te.AsQueryable(); 

    Item pr2 = new Item(); 
    pr2.contentid = 0; 
    pr2.taxid = 0; 
    pr2.taxids = numbers2.AsEnumerable(); 
    pr2.taxname = "nameItem2"; 
    List<Item> te2 = new List<Item>(); 
    te2.Add(pr2); 
    IQueryable<Item> er2 = te2.AsQueryable(); 

    IQueryable<Item> both = er.Intersect(er2, new ItemComparer()); 

Здесь я использую собственный компаратор ItemComparer Вот код для этого:.

public class ItemComparer : IEqualityComparer<Item> 
{ 
    // items are equal if their names and item numbers are equal. 
    public bool Equals(Item x, Item y) 
    { 
     //Check whether the compared objects reference the same data. 
     if (Object.ReferenceEquals(x, y)) return true; 

     //Check whether any of the compared objects is null. 
     if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null)) 
      return false; 

     //Check whether the items' properties are equal. 
     return x.taxids.Intersect(y.taxids).SequenceEqual(x.taxids); 
    } 

    // If Equals() returns true for a pair of objects 
    // then GetHashCode() must return the same value for these objects. 
    public int GetHashCode(Item item) 
    { 
     //Check whether the object is null 
     if (Object.ReferenceEquals(item, null)) return 0; 

     //Get hash code for the Name field if it is not null. 
     int hashItemName = item.taxids == null ? 0 : item.taxids.GetHashCode(); 

     //Calculate the hash code for the item. 
     return item.taxids.GetHashCode(); 

     //return "a".GetHashCode(); 
    } 
} 

Проблема в том, что переменная both не имеет ничего в поле taxids, обычно у меня должен быть список «5» «1».

Я знаю, что значение hashCode должно быть одинаковым при сравнении. но taxids никогда не будет прежним. Потому что мы ищем строки в другом списке строк.

Кто-нибудь может помочь мне с этой проблемой?

(Также маленький вопрос: Если я вернусь всегда один и тот же хэш-код для всего, как "a".GetHashCode() => Если эта работа или нет

Заранее спасибо

ответ

2

Я думаю, ваша проблема в том, что у вас нет двунаправленное равенство. в зависимости от того, на какой стороне находится ваш объект, pr и pr 2 не равны.

Я не уверен, есть ли гарантия, какой объект является x, а какой y - в вашем компаменте. Что делать, если pr2 заканчивается номером x в вашем сравнении?

Что касается хеш-кода, вы делаете taxids.GetHashCode() - это всего лишь список, а не имя и ничего не скажу о равенстве.

0
return x.taxids.Intersect(y.taxids).SequenceEqual(x.taxids); 

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

return x.taxids.Intersect(y.taxids) 
       .OrderBy(x => x) 
       .SequenceEqual(x.taxids.OrderBy(x => x)); 

Также вы должны предоставить соответствующую реализацию GetHashCode(), реализация по умолчанию не зависит от фактических элементов в списке, поэтому не приведет к тому же хэш-коду для двух разных экземпляров Item, которые имеют одинаковые элементы в коллекции. Более подходящую реализацию для вашего дела можно найти в this other SO post.

+0

При выполнении указателя он всегда возвращается в том же порядке. Но спасибо за информацию – Ozkan

+0

Он вернет элементы в том порядке, в котором они были собраны (и даже на том, на что вы не должны положиться) - в одной из коллекций. Это не обязательно то же самое, что и элементы в другой коллекции, поэтому необходим повторный порядок. – BrokenGlass

+0

Спасибо за информацию. И для метода getHashcode. Может быть, ты знаешь больше меня. Могу ли я использовать всегда один и тот же хэш-код для всего? Например: '' a .GetHashCode() '.Потому что у меня никогда не будет двух одинаковых списков. В URL-адресе, который вы указали, списки можно сделать одинаковыми, делая разные, но у меня есть совершенно разные элементы в списке. – Ozkan

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

  • Нет связанных вопросов^_^