我有一个简单的项目,使用MVC模式,ET和WCF。它使用Dijkstra来寻找城市之间的路径。 This is the class itself.
但是,在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
有人能看出出现这种情况的原因吗?
修改
我做了进一步的测试,用这个片段打印了所有可能的对象,并在对象中打了there is no difference(当然除了哈希):
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();
}
}
答案 0 :(得分: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));
}