字典<myfield,myobject =“”>其中myField是myObject的成员</myfield,>

时间:2012-07-30 15:39:25

标签: c# hash hashmap

在C#中是否可以创建由对象组成的字典,这样Key只是对字段值的引用(或Value的字段,因为它是) ,以确保index == myDictionary[index].myField

例如,想象一下标准的C#Dictionary。假设我有Car个对象:

class Car {
    string name;
    int wheels;
    double weight;
    double horsepower;
    double topSpeed;

    // Appropriate constructors
}

我要存储在此词典中,按名称索引:

var cars = new Dictionary<string, Car>();

var newCar = Car("Ford", 4, 2387.4, 4535.7, 128.2);
cars["Ford"] = newCar;

我的标准无法保证,因为我可以这样做:

cars["Ford"].name = "not Ford";

条件被打破了。我可以简单地从name中移除Car字段,但后来汽车本身就不会知道自己的名字 - 即使我们设置了这个时代的汽车也是一个令人尴尬的情况除了性能成本。

所以我的问题:是否可以在C#中轻松制作哈希映射,使哈希值始终等于哈希元素的某些部分,并且只要元素是哈希值就会更新?

4 个答案:

答案 0 :(得分:2)

您正在描述KeyedCollection类,但如果在将项目的密钥添加到集合后更改项目的密钥,则会遇到问题。

如果您想要一个哈希集合处理其元素标识属性的更改,您可以在类型(示例中为Car)上实现INotifyPropertyChanged,并让集合重新定位项目(或删除并重新根据需要添加它们。这将是低效且非常容易出错的。

答案 1 :(得分:0)

您可以使用C#http://msdn.microsoft.com/en-us/library/2549tw02.aspx

中的索引器来实现它

答案 2 :(得分:0)

您可以考虑将课程设计更改为:

class Car { public string name { get; private set; } }

因此,您将无法更改标识对象的部分。否则,字典似乎是一个很好的方法。

答案 3 :(得分:0)

一种替代方法是使用以下行构建您自己的指定CarDictionary带有基于字符串的索引器(假设Name字段/属性为public):

public class CarDictionary : List<Car>
{
    public Car this[string name]
    {
        get { return this.Single(car => car.Name.Equals(name)); }
        set {
            var oldCar = this.SingleOrDefault(car => car.Name.Equals(name));
            if (oldCar != null) base.Remove(oldCar);
            value.Name = name;
            base.Add(value);
        }
    }

    public new void Add(Car car)
    {
        if (this.Any(c => c.Name.Equals(car.Name))) 
            throw new InvalidOperationException("Dictionary already contains a Car with the same name");
        base.Add(car);
    }
}

此外,您需要重新实现或隐藏其他基类方法,例如AddRangeRemove等,以确保收集不会被意外损坏。

如果您现在初始化汽车“词典”并添加 Ford

var cars = new CarDictionary();

var newCar = new Car("Ford", 4, 2387.4, 4535.7, 128.2);
cars["Ford"] = newCar;

词典状态是:

Number of cars: 1, name of first car: Ford

如果您尝试:

cars["Ford"].Name = "not Ford";

词典状态将是:

Number of cars: 1, name of first car: not Ford

接下来,使用重新实施的Add方法添加新的 Ford

cars.Add(new Car("Ford", 6, 4000.0, 500.0, 100.0));

将产生以下字典状态:

Number of cars: 2, name of last car: Ford

尝试使用Add方法添加另一个 Ford 会产生异常:

var anotherFord = new Car("Ford", 3, 1000.0, 50.0, 120.0);
cars.Add(anotherFord);

InvalidOperationException: Dictionary already contains a Car with the same name

但是如果您使用索引器,则新的 Ford 将替换旧的:

cars["Ford"] = anotherFord;

Number of cars: 2, name of last car: Ford

最后,使用索引器向字典添加新Car的一个特点是索引器可能(应该?)更改添加的Car的名称:

cars["thought this was a Ford?"] = anotherFord;

Number of cars: 3, name of last car: thought this was a Ford?

据我所知,这将是索引器设置器的预期行为。如果不希望出现这种情况,只需删除行

即可
value.Name = name;

来自索引器设置器实现。