вызов метода с двумя одинаковыми параметрами возвращает два разных результата
У меня есть простой проект, использующий шаблон MVC, ET и WCF. Он использует Дейкстру для поиска путей между городами. Это и есть сам класс.
Однако при вызовеFindPathFromCityToCity()
с двумя одинаковыми списками в объекте map
, такими же from
и to
, когда он находится в обычном консольном приложении, он возвращает желаемый результат. Однако, при использовании из WCF, он терпит неудачу на строке 39 с исключением System.Collections.Generic.KeyNotFoundException
.
Чтобы проверить, является ли мой ввод неверным, я добавил эту запись в файл txt (строка 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:logcheck.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)); }