c#Dictionary,类为Key

时间:2017-09-03 13:07:44

标签: c# class dictionary key 2d

我正在攻读电子工程,我是c#的初学者。我已经测量了数据,并希望以2个方式存储它。我以为我可以写这样一本字典:

Dictionary<Key, string>dic = new Dictionary<Key, string>(); 

“Key”在这里是一个拥有两个int变量的自有类。现在我想将数据存储在这个词典中,但到目前为止它还没有用。如果我想用特殊的密钥读取数据,错误报告说,密钥在字典中不可用。

这里是班级钥匙:

public partial class Key
{
    public Key(int Bahn, int Zeile) {
    myBahn = Bahn;
    myZeile = Zeile;

}
    public int getBahn()
    {
        return myBahn;
    }
    public int getZeile()
    {
        return myZeile;
    }
    private  int myBahn;
    private int myZeile;
}

为了测试它,我做了类似的事情:

获取元素:

Key KE = new Key(1,1);
dic.Add(KE, "hans");
...

获取元素:

Key KE = new Key(1,1);
monitor.Text = dic[KE];

有人有想法吗?

2 个答案:

答案 0 :(得分:6)

您需要覆盖自己类中的方法GetHashCodeEquals,以将其用作关键字。

class Foo 
{ 
    public string Name { get; set;} 
    public int FooID {get; set;}
    public override int GetHashCode()             
    {  
           return FooID; 
    }
     public override bool Equals(object obj) 
    { 
             return Equals(obj as Foo); 
    }

    public bool Equals(Foo obj)
     { 
          return obj != null && obj.FooID == this.FooID; 
     }
}

答案 1 :(得分:0)

尽管您可以通过实现自己的 EqualsGetHashCode 来使用类作为键,但如果您还不熟悉 C#,我不建议您这样做。

这些方法将由 C# 内部库调用,它们期望它们完全按照规范工作,优雅地处理所有边缘情况。如果您将错误放入其中,您可能会陷入令人不快的挠头会议。

在我看来,使用已经支持散列和比较的经过验证的、真实的和经过测试的现有类型,在现场创建一个键的效率和方式不会降低。

根据您的角坐标,例如:

int Bahn = 15;
int Zeile = 30;

您可以使用字符串(例如 "15,30"):

String Key (int Bahn, int Zeile) { return $"{Bahn},{Zeile}"; }

var myDict = new Dictionary<string, string>();
myDict.Add (Key(Bahn,Zeile), myString);

或者两个元素的元组(例如 <15,30>),如果您需要更高效的东西:

Tuple<int,int> Key (int Bahn, int Zeile) { return Tuple.Create(Bahn,Zeile); }

var myDict = new Dictionary<Tuple<int, int>, string>();
myDict.Add (Key(Bahn,Zeile), myString);

或者如果范围足够小以适合整数(例如15+30*360),如果您需要更有效的东西,则仅是两个角度的组合:

int Key (int Bahn, int Zeile) { return Bahn+360*Zeile; }

var myDict = new Dictionary<int, string>();
myDict.Add (Key(Bahn,Zeile), myString);

这似乎比:

   class Key {
      // truckloads of code to implement the class,
      // not to mention testing it thourougly, including edge cases
   }

    var myDict = new Dictionary<Key, string>();
    myDict.Add (new Key(Bahn,Zeile), myString);

密钥的可变性

另外,请注意,只要您的键用于索引条目,它们就必须是不可变的。

如果在使用键添加元素后更改 BahnZiel 的值,您的字典会变得很糟糕。

行为未定义,但如果内部库最终检测到不一致的状态(例如多个条目由同一键索引),您很可能会丢失随机条目,导致内存泄漏并可能因异常而崩溃。

例如:

var myKey = new Key(15, 30);

for (String data in row_of_data_sampled_every_10_degrees)
{
   myDict.Add (myKey, data); // myKey must remain constant until the entry is removed
   myKey.Bahn += 10;         // changing it now spells the death of your dictionary
}

关于散列角坐标的旁注

现在的问题是,为整数、字符串和元组提供的通用哈希函数不太可能为您的特定数据集产生最佳结果。

我建议从一个简单的解决方案开始,只有在遇到实际性能问题时才求助于专门的代码。在这种情况下,您最好使用更适合空间索引的数据结构(通常在极坐标情况下使用 quadtree,如果您想从扫描仪重建 3D 模型,则使用 octree数据)。