字典能根据键快速查找值,也可以自由的添加元素和删除元素。键会转换成一个散列,利用散列创建一个数字,它将索引和值关联起来。索引包含一个到到值得链接。键必须重写GetHashCode()方法。Equals()方法必须重写GetHashCode(),不然编译会出错。字典常用字符串做键。
using System;
using System.Collections.Generic;
namespace Sample
{
public class MainEntryPoint
{
static int Main(string[] args)
{
//容量一般设置为素数 如果设置的不是
//类会使用传递给构造函数整数的最近一个素数
var employees = new Dictionary<EmployeeId, Employee>(31);
var julyId = new EmployeeId("C3755");
var july = new Employee("July",379025.00m,julyId);
employees.Add( julyId, july);
Console.WriteLine(july);
var joynId = new EmployeeId("F3547");
var joyn = new Employee("Joyn",403466.00m,joynId);
employees.Add(joynId, joyn);
Console.WriteLine(joyn);
var johnId = new EmployeeId("C3386");
var john = new Employee("John",415216.00m,johnId);
//通过索引把值传递进字典
employees[johnId] = john;
Console.WriteLine(john);
Console.WriteLine();
while(true)
{
Console.Write("Enter employee id(X to exit)>");
var userInput = Console.ReadLine();
userInput = userInput.ToUpper();
if(userInput == "X")
break;
EmployeeId id;
try
{
id = new EmployeeId(userInput);
Employee employee;
//先判断是否有对应这个键的值
//返回布尔类型 还有一个out参数带回这个值
if(!employees.TryGetValue(id, out employee))
{
Console.WriteLine("Employee with id {0} does not exist",id);
}
else
{
Console.WriteLine(employee);
}
}
catch (EmployeeIdException ex)
{
Console.WriteLine(ex.Message);
}
}
return 0;
}
}
[Serializable]
public class EmployeeIdException : Exception
{
public EmployeeIdException(string message) : base(message)
{
}
}
[Serializable]
public struct EmployeeId :IEquatable<EmployeeId>
{
private readonly char prefix;
private readonly int number;
public EmployeeId(string id)
{
prefix = (id.ToUpper())[0];
int numLength = id.Length - 1;
try
{
number = int.Parse(id.Substring( 1, numLength > 6 ? 6 : numLength));
}
catch (FormatException)
{
throw new EmployeeIdException("Invalid EmployeeId format");
}
}
public override string ToString()
{
return prefix.ToString()+string.Format("{0:6:000000}", number);
}
//把数值平均的分布在整型范围内
public override int GetHashCode()
{
return (number ^ number << 16) * 0x15051505;
}
public bool Equals(EmployeeId other)
{
if(other == null)
return false;
else
return (prefix == other.prefix && number == other.number);
}
public override bool Equals(object obj)
{
return Equals((EmployeeId)obj);
}
public static bool operator ==(EmployeeId left, EmployeeId right)
{
return left.Equals(right);
}
public static bool operator !=(EmployeeId left, EmployeeId right)
{
return !(left == right);
}
}
[Serializable]
public class Employee
{
private string name;
private decimal salary;
private EmployeeId id;
public Employee(string name, decimal salary, EmployeeId id)
{
this.name = name;
this.salary = salary;
this.id = id;
}
public override string ToString()
{
return string.Format("{0}: {1,-20} {2 : C}",id.ToString(), name, salary);
}
}
}