Вызов метода с двумя одинаковыми параметрами возвращает два разных результата

У меня есть простой проект, используя шаблон MVC, ET и WCF. Он использует Dijkstra, чтобы найти пути между городами. Это сам класс.

Однако при звонке FindPathFromCityToCity() с двумя одинаковыми списками в map объект тот же from а также to, когда он находится в обычном консольном приложении, он возвращает желаемый результат. Однако при использовании из WCF происходит сбой в строке 39, за исключением System.Collections.Generic.KeyNotFoundException,

Чтобы проверить, является ли мой ввод неправильным, я добавил, что запись в текстовый файл (строки с 17 по 27) и вот что это приводит (TL;DR - оба абсолютно одинаковы):

Приставка:

COUNT: 14 - RANGE 120
FROM: Aalborg - TO: Copenhagen
C: Frederikshavn - E: 2 - T: BLL.BatteryCenter
C: Aalborg - E: 6 - T: BLL.BatteryCenter
C: Hobro - E: 4 - T: BLL.BatteryCenter
C: Randers - E: 6 - T: BLL.BatteryCenter
C: Viborg - E: 8 - T: BLL.BatteryCenter
C: Aarhus - E: 8 - T: BLL.BatteryCenter
C: Herning - E: 6 - T: BLL.BatteryCenter
C: Vejle - E: 8 - T: BLL.BatteryCenter
C: Kolding - E: 6 - T: BLL.BatteryCenter
C: Odense - E: 6 - T: BLL.BatteryCenter
C: Aabenraa - E: 2 - T: BLL.BatteryCenter
C: Koge - E: 4 - T: BLL.BatteryCenter
C: Copenhagen - E: 2 - T: BLL.BatteryCenter
C: Soro - E: 4 - T: BLL.BatteryCenter

WCF:

COUNT: 14 - RANGE 120
FROM: Aalborg - TO: Copenhagen
C: Frederikshavn - E: 2 - T: BLL.BatteryCenter
C: Aalborg - E: 6 - T: BLL.BatteryCenter
C: Hobro - E: 4 - T: BLL.BatteryCenter
C: Randers - E: 6 - T: BLL.BatteryCenter
C: Viborg - E: 8 - T: BLL.BatteryCenter
C: Aarhus - E: 8 - T: BLL.BatteryCenter
C: Herning - E: 6 - T: BLL.BatteryCenter
C: Vejle - E: 8 - T: BLL.BatteryCenter
C: Kolding - E: 6 - T: BLL.BatteryCenter
C: Odense - E: 6 - T: BLL.BatteryCenter
C: Aabenraa - E: 2 - T: BLL.BatteryCenter
C: Koge - E: 4 - T: BLL.BatteryCenter
C: Copenhagen - E: 2 - T: BLL.BatteryCenter
C: Soro - E: 4 - T: BLL.BatteryCenter

Может ли кто-нибудь увидеть причину этого?


РЕДАКТИРОВАТЬ:

Я сделал дальнейшие тесты, печатая все возможные объекты с этим фрагментом, и нет никакой разницы в объектах (кроме хэша, конечно):

using (System.IO.StreamWriter file = new System.IO.StreamWriter(@"C:\log\check.txt", true))
{
    foreach (var m in map.Stations)
    {
        file.WriteLine(" --- {0} - {1} - {2} - {3} --- ", m.name, m.Edgelist.Count, m.GetType(), m.GetHashCode());
        foreach(var e in m.Edgelist)
        {
            file.WriteLine();
            file.WriteLine(" # {0} - {1} - {2} - {3}", e.BatteryStation.name, e.BatteryStation1.name, e.distance, e.edgeID);
            file.WriteLine(" + {0} - {1} - {2}", e.BatteryStation.GetType(), e.BatteryStation.stationID, e.BatteryStation.GetHashCode());
            file.WriteLine(" - {0} - {1} - {2}", e.BatteryStation1.GetType(), e.BatteryStation1.stationID, e.BatteryStation1.GetHashCode());
        }
        file.WriteLine();
   }
}

1 ответ

Решение

Это все зависит от механики BatteryCenter объект.

Вызывающий код передает его в качестве параметра, а функция использует его в качестве ключа на карте.

Вы переопределили функции Equals а также GetHashCode на BatteryCenter?

Если нет, то поиск по словарю будет искать именно этот объект. Не BatteryCenter со всеми одинаковыми полями, но объект с той же ссылкой.

Клиент WCF будет проходить в эквивалентном, но, тем не менее, другом BatteryCenter, который словарь не может найти.

После добавления переопределений для BatteryCenter.Equals а также BatteryCenter.GetHashCode это вероятно будет работать.

например

public override int GetHashCode() 
{
     return this.stationID.GetHashCode() ^ this.name.GetHashCode();
}

public override bool Equals(Object obj) 
{
     if(Object.ReferenceEquals(this, obj))
     {
          return true;
     }
     BatteryStation other = obj as BatteryStation;
     if(Object.ReferenceEquals(other, null))
     {
         return false;
     }
     return ((this.stationID == other.stationID) && (this.name == other.name));
}
Другие вопросы по тегам