C#词典 - 自定义对象

时间:2013-02-26 16:34:50

标签: c# collections dictionary

我之前从未使用过词典,我只是想了解更多关于它们的信息。

在自定义对象方面,我有点迷失。是否可以像下面的类一样使用自定义对象作为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?

6 个答案:

答案 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实例匹配放置相同CarId属性的差异实例,但它们指向不同的对象)甚至不知道

你不希望这是可能的

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的键,对于它来说,EqualsGetHashCode的实现正确定义“等式”对您的对象意味着什么很重要。

这两种方法的默认实现通常是不合适的,因为默认情况下它们只是比较引用,这意味着当你可能想要它们时,具有相同值的两个不同对象将不会“相等”。 / 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();
        }
    }