C#字典重复键问题:游戏脚本副本如何修改Point3D键值?
解决“Item with the same key has already been added”错误方案
这个错误的核心原因是**Dictionary<Point3D, Map>中添加了重复的Point3D键**——字典要求所有键必须唯一,不能重复。针对你复制脚本修改位置的场景,可通过以下方式解决:
1. 检查单个脚本实例的字典键唯一性
复制脚本后修改坐标时,务必保证当前脚本的ListOfLocations里所有Point3D坐标都是唯一的,避免出现重复键:
// 错误示例:存在重复的Point3D键 protected Dictionary<Point3D, Map> ListOfLocations = new Dictionary<Point3D, Map>() { { new Point3D(1185, 1838, 0), Map.Felucca }, { new Point3D(1185, 1838, 0), Map.Trammel }, // 重复键触发错误 }; // 正确示例:所有坐标唯一 protected Dictionary<Point3D, Map> ListOfLocations = new Dictionary<Point3D, Map>() { { new Point3D(1185, 1838, 0), Map.Felucca }, { new Point3D(1190, 1840, 0), Map.Trammel }, };
2. 避免多实例共享字典
如果你误将ListOfLocations声明为static静态字段,所有脚本实例会共用同一个字典,不同实例添加相同键就会报错。将static修饰符移除,让每个脚本实例拥有独立的字典:
// 错误写法:静态字段导致多实例共享字典 protected static Dictionary<Point3D, Map> ListOfLocations = ...; // 正确写法:实例级字段,每个脚本独立持有字典 protected Dictionary<Point3D, Map> ListOfLocations = ...;
3. 动态添加键时做存在性检查
如果需要动态往字典里添加坐标(而非初始化时写死),先检查键是否存在再执行添加操作,避免报错:
public void AddLocation(Point3D point, Map map) { if (!ListOfLocations.ContainsKey(point)) { ListOfLocations.Add(point, map); } else { // 可选逻辑:覆盖旧值或打印日志提醒 // ListOfLocations[point] = map; Console.WriteLine($"坐标 {point} 已存在,跳过添加"); } }
4. 确保Point3D的相等性逻辑正确
如果Point3D是自定义类型,必须正确实现Equals和GetHashCode方法——字典依赖这两个方法判断键是否相等。如果逻辑缺失,可能出现“视觉不同但被判定为相同”或“视觉相同但未被判定为相同”的问题:
public struct Point3D { public int X { get; } public int Y { get; } public int Z { get; } public Point3D(int x, int y, int z) { X = x; Y = y; Z = z; } // 重写Equals判断坐标是否一致 public override bool Equals(object obj) { return obj is Point3D other && X == other.X && Y == other.Y && Z == other.Z; } // 重写GetHashCode生成唯一哈希值 public override int GetHashCode() { return HashCode.Combine(X, Y, Z); } }
内容的提问来源于stack exchange,提问作者Gameover Just End
相关产品推荐
相关产品推荐

