在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#中轻松制作哈希映射,使哈希值始终等于哈希元素的某些部分,并且只要元素是哈希值就会更新?
答案 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);
}
}
此外,您需要重新实现或隐藏其他基类方法,例如AddRange
,Remove
等,以确保收集不会被意外损坏。
如果您现在初始化汽车“词典”并添加 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;
来自索引器设置器实现。