这种看起来像是一个菜鸟问题,但我没有特别找到这个问题的答案.
我有这门课:
public class Quotes{
public string symbol;
public string extension
}
Run Code Online (Sandbox Code Playgroud)
我正在使用这个:
HashSet<Quotes> values = new HashSet<Quotes>();
Run Code Online (Sandbox Code Playgroud)
但是我可以多次添加相同的Quotes对象.例如,我的Quotes对象可能具有等于'A'的'symbol'和'= n'的'extension',并且此Quotes对象在HashSet中出现多次(通过调试模式查看Hashset).打电话时我曾想过
values.Add(new Quotes(symb, ext));
Run Code Online (Sandbox Code Playgroud)
使用相同的symb和ext,将返回'false'并且不会添加元素.我感觉它与HashSet添加新对象时比较Quotes对象有关.任何帮助将不胜感激!
Ken*_*rey 50
我猜你正在Quotes
用相同的值创建一个新的.在这种情况下,他们是不平等的.如果它们应被视为相等,则覆盖Equals和GetHashCode方法.
public class Quotes{
public string symbol;
public string extension
public override bool Equals(object obj)
{
Quotes q = obj as Quotes;
return q != null && q.symbol == this.symbol && q.extension == this.Extension;
}
public override int GetHashCode()
{
return this.symbol.GetHashCode() ^ this.extension.GetHashCode();
}
}
Run Code Online (Sandbox Code Playgroud)
Ree*_*sey 19
我曾经想过,当
values.Add(new Quotes(symb, ext));
使用相同的symb和ext 调用时,将返回'false'并且不会添加元素.
不是这种情况.
HashSet将使用GetHashCode
和Equals
确定对象的相等性.现在,由于您没有覆盖这些方法Quotes
,因此System.Object
将使用默认的引用相等性.每次添加新的Quote时,它都是唯一的对象实例,因此HashSet将其视为唯一对象.
如果重写Object.Equals
和Object.GetHashCode
,因为你希望它会工作.
HashSets首先根据其计算的哈希值来比较条目GetHashCode
.
默认实现返回基于对象本身的哈希码(每个实例之间不同).
只有当哈希值相同时(基于实例的哈希值非常不可能),才会调用Equals方法并用于明确比较两个对象.
你必须选择:
例:
public override int GetHashCode()
{
return (this.symbol == null ? 0 : this.symbol.GetHashCode())
^ (this.extension == null ? 0 : this.extension.GetHashCode());
}
public override bool Equals(object obj)
{
if (Object.ReferenceEquals(this, obj))
return true;
Quotes other = obj as Quotes;
if (Object.ReferenceEquals(other, null))
return false;
return String.Equals(obj.symbol, this.symbol)
&& String.Equals(obj.extension, this.extension);
}
Run Code Online (Sandbox Code Playgroud)
小智 6
只是想在 Kendall 的回答中解决一些问题(由于某些奇怪的原因无法发表评论)。
return this.symbol.GetHashCode() ^ this.extension.GetHashCode();
Run Code Online (Sandbox Code Playgroud)
请注意,xor 函数是一种非常容易发生冲突的组合两个散列的方法,尤其是当它们都是相同类型时(因为每个符号 == 扩展名的对象都会散列为 0)。即使它们不是同一类型或不太可能彼此相等,这也是不好的做法,习惯它可能会导致不同设备出现问题。
相反,将一个散列乘以一个小的素数,然后添加第二个,例如:
return 3 * this.symbol.GetHashCode() + this.extension.GetHashCode();
Run Code Online (Sandbox Code Playgroud)