Dar*_*rke 6 c# generics inheritance dictionary interface
我正在做一个练习来帮助我理解和学习泛型的使用,以及对接口和接口继承的理解。这是通过实现和使用我自己的类来完成的。
我认为我已经1成功完成了部分工作(遵循教程),并且能够毫无问题地进行散列并添加到我的字典中。如果解决方案中有我遗漏的部分,1请随时告诉我。
第二部分是主要问题。根据我的理解,我应该让钥匙是 一个城市的latitude和。longitude我自己的 Dictionary 实现Dict是这样的,Dict<K, V>所以键不可能有 2 个值。
我认为这就是struct可以进来并传递 mystruct作为密钥,同时存储latitude和 的值的地方longitude。
下面我将尝试概述练习描述和要求,以使我的问题更容易理解。
该练习有 2 个部分
第1部分
在这一部分中,您将创建自己的类来实现 IDictionary<K,V>。
为了实现 IDictionary<K,V> 您必须实现 ICollection 和 IEnumerable 接口。
不允许您使用
C#Dictionary 实现作为委托,因为这会使练习变得无关紧要。
第2部分
我们希望使用最近创建的 Dictionary 类将纬度和经度值映射到其匹配的城市。
键本身应该是一个表示由 a和 a
GeoLocation组成的类。制作所有必要的函数和运算符重载,以便可以使用此类作为 Dictionary 类的键latitudelongitude
字典:
public class Dict<K, V>:IEnumerable<KeyValuePair<K,V>>
{
private const int INI_Size = 16;
LinkedList<KeyValuePair<K, V>>[] values;
public Dict()
{
this.values = new LinkedList<KeyValuePair<K, V>>[INI_Size];
}
public int Count { get; private set; }
public int Capacity
{
get
{
return this.values.Length;
}
}
public void Add(K key, V value)
{
var hash = this.HashKey(key);
if(this.values[hash]== null)
{
this.values[hash] = new LinkedList<KeyValuePair<K, V>>();
}
var keyExistsAlready = this.values[hash].Any(p => p.Key.Equals(key));
if (keyExistsAlready)
{
throw new InvalidOperationException("key already exist");
}
var pair = new KeyValuePair<K, V>(key, value);
this.values[hash].AddLast(pair);
this.Count++;
if (this.Count >= this.Capacity * 0.75)
{
this.ResizeAndReAddValues();
}
}
public V Find (K key)
{
var hash = this.HashKey(key);
if(this.values[hash] == null)
{
return default(V);
}
var collection = this.values[hash];
return collection.First(p => p.Key.Equals(key)).Value;
}
public bool ContainsKey(K key)
{
var hash = HashKey(key);
if (this.values[hash] == null)
{
return false;
}
var collection = this.values[hash];
return collection.Any(pair => pair.Key.Equals(key));
}
private int HashKey(K key)
{
var hash = Math.Abs(key.GetHashCode()) % this.Capacity;
return hash;
}
private void ResizeAndReAddValues()
{
var cachedValues = this.values;
this.values = new LinkedList<KeyValuePair<K, V>>[2 * this.Capacity];
this.Count = 0;
foreach (var collection in cachedValues)
{
if (collection != null)
{
foreach (var value in collection)
{
this.Add(value.Key, value.Value);
}
}
}
}
public IEnumerator<KeyValuePair<K, V>> GetEnumerator()
{
foreach(var collection in this.values)
{
if (collection != null)
{
foreach (var value in collection)
{
yield return value;
}
}
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
}
Run Code Online (Sandbox Code Playgroud)
地理位置:
public struct GeoLocation
{
public float X;
public float Y;
public GeoLocation(float x, float y)
{
X = x;
Y = y;
}
}
Run Code Online (Sandbox Code Playgroud)
如果我使用已经实现Dictionary的System.Collections.Generic
var dict = new Dictionary<GeoLocation, string>() {
[new GeoLocation(12, 78)] = "Paris",
[new GeoLocation(98, -18)] = "Frankfurt"
};
//test for part 1 (works)
/* var d = new Dict<int, string>
{
{ 10, "Washington" }
};*/
Run Code Online (Sandbox Code Playgroud)
这是可能的,我会对我的实现做同样的事情还是解决方案与我想象的完全不同?
另一件要补充的事情是,正如我之前所说,如果我的实现也有部分错误,1请告诉我,因为我正在尝试通过编码和提问来理解事物。
我不会给你一个即插即用的答案,因为这是一个练习,我发现为你解决它是有问题的。
我将为您提供一些应该足够的提示,以及对您的代码的一些反馈。
首先:
实现 IDictionary<TK, TV> 以免费获取您帖子中提到的语法(以及每个人都知道如何在 C# 中使用的标准化 API)。
一些一般提示:
private int HashKey(TKey key)
{
var hash = Math.Abs(key.GetHashCode()) % this.Capacity;
return hash;
}
Run Code Online (Sandbox Code Playgroud)
可能
private int HashKey(TKey key)
=> Math.Abs(key.GetHashCode()) % this.Capacity;
Run Code Online (Sandbox Code Playgroud)
和
public bool IsReadOnly
{
get { return false; }
}
Run Code Online (Sandbox Code Playgroud)
可能
public bool IsReadOnly => false;
// or
public bool IsReadOnly { get; } = false;
Run Code Online (Sandbox Code Playgroud)
一些更具体的提示:
字典中使用的键(这是一种简化,但通常是最相关的两个)根据两个属性进行行为:
GetHashCode函数必须为那些被视为“相等”的对象返回相同的哈希码GetHashCode对于许多不相等的对象可能返回相同的值。这很好——如果有很多碰撞,可能会损害性能,但对于一组相同的对象来说,它不能是唯一的。微软表示:不要通过测试哈希码是否相等来确定两个对象是否相等。
因此,在通过哈希码找到候选者后,必须检查是否相等。您已经在 find 方法中正确执行了此操作。
因此:为您的密钥正确实施散列和相等。C# 中的默认值是(对于您自己的类)引用相等。覆盖用作键的类型的相等函数和散列函数。
结构很有趣,因为它们默认按值进行比较,并且 GetHashCode 的行为方式对您有用。现代方法是使用记录(或记录结构)来免费获取相等性和哈希码。我建议您充分理解这两个概念,以便手动实现它们,以避免将来可能出现的误解和错误!