我之前从未使用过词典,我只是想了解更多关于它们的信息。
在自定义对象方面,我有点迷失。是否可以像下面的类一样使用自定义对象作为Key,而不是值?
class Car
{
public Car(int id, string model)
{
ID = id;
Model = model;
}
public int ID { get; private set; }
public string Model { get; private set; }
}
如果你在哪里创建一个字典,就像这样: -
Dictionary<Car, bool> Cars = new Dictionary<Car, bool>();
在搜索词典内容时,如何将Car对象用作Key?
答案 0 :(得分:3)
是的,这很有可能,但需要注意一个非常重要的警告。
字典使用默认相等比较检查密钥。对于自定义类对象,这意味着“这是对同一对象的引用”。不是“这是一个具有相同数据的对象”。
例如:
var car1 = new Car(1, "Avalon");
var car2 = car1;
var car3 = new Car(1, "Avalon");
Cars.Add(car1, true);
Console.WriteLine(Cars[car2]); // writes "True";
Console.WriteLine(Cars[car3]); // throws a KeyNotFoundException
您可以通过覆盖您班级的GetHashValue()
和Equals()
来解决此问题。请参阅here。
答案 1 :(得分:3)
您需要为Equals()
类型实施GetHashCode()
和Car
。由于Car是一个引用类型,您可能会在字典中为两个Car实例匹配放置相同Car
(Id
属性的差异实例,但它们指向不同的对象)甚至不知道
你不希望这是可能的
var carMap = new Dictionary<Car, string>();
var carOne = new Car { Id = 1 };
var careTwo = new Car { Id = 1 };
carMap[carOne] = "one";
// you want this line to fail since a Car with this Id is already present
carMap[carTwo] = "two";
GetHasCode()
,您可以返回Id.GetHashCode()
对于Equals()
,只需执行标准样板检查,例如检查类型是否相同等等。
This link提供了有关实施GetHashCode()
答案 2 :(得分:2)
要将对象用作Dictionary
的键,对于它来说,Equals
和GetHashCode
的实现正确定义“等式”对您的对象意味着什么很重要。
这两种方法的默认实现通常是不合适的,因为默认情况下它们只是比较引用,这意味着当你可能想要它们时,具有相同值的两个不同对象将不会“相等”。 / p>
一旦你有了这些方法的合理实现,就可以使用字典索引器将Car
实例放入其中,并获取与该Car
相关联的布尔值。
答案 3 :(得分:2)
来自MSDN:(http://msdn.microsoft.com/en-us/library/xfhwa508(v=vs.80).aspx)
If type TKey implements the System.IEquatable generic interface, the default equality comparer uses that implementation.
因此,在您的情况下,您需要实施IEquatable<Car>
,例如:
class Car : IEquatable<Car>
{
public Car(int id, string model)
{
ID = id;
Model = model;
}
public int ID { get; private set; }
public string Model { get; private set; }
public bool Equals(Car other)
{
return this.ID == other.ID;
}
}
答案 4 :(得分:1)
var car1 = new Car(1,"A300");
var car2 = new Car(1,"A400");
添加到词典
Cars.Add(car1 ,true);
Cars.Add(car2 ,true);
Cars.ContainsKey(car1) - //which returns boolean can be used to check for the exisitence of a key
获取可以使用的值
var x=Cars[car1];
使用不在字典集合中的密钥会引发异常。
答案 5 :(得分:1)
在您的情况下,您尝试将自定义对象用作字典中的键,在字典数据结构中,每个键都是唯一的,因此您需要在数据结构中提供一种方法来区分一个对象与其他对象。
这是通过重写GetHashCode()方法完成的,实现IEquatable是可选的,但它可以清楚地表明你想要做的事情。
class Car : IEquatable<Car>
{
public Car(int id, string model)
{
ID = id;
Model = model;
}
public int ID { get; private set; }
public string Model { get; private set; }
public bool Equals(Car other)
{
return !ReferenceEquals(null, other) && ID == other.ID;
}
// This is a must if you like to correctly use your object as a key in dictionary
public override int GetHashCode()
{
return ID.GetHashCode();
}
}