问题描述
我将用户table-column-configuration存储在一个简单类中:
public class ColumnUserSetting : IComparable<ColumnUserSetting>
{
public String TableWrapperName { get; set; }
public String ColumnName { get; set; }
public Boolean Enabled { get; set; }
public int Width { get; set; }
public int Position { get; set; }
}
}
这些类存储在SortedSet中-因此,它需要实现IComparable<>
,我根据位置实现了该功能,正如文档中所说的那样,它是关于位置比较的-没有什么可以说它们不能相同:
public class ColumnUserSetting : IComparable<ColumnUserSetting>
{
public String TableWrapperName { get; set; }
public String ColumnName { get; set; }
public Boolean Enabled { get; set; }
public int Width { get; set; }
public int Position { get; set; }
public int Compareto(ColumnUserSetting other)
{
if (other.Position == this.Position) return 0;
if (other.Position > this.Position) return -1;
return 1;
}
}
但是,在同一运行中,这似乎表现为“等于”。具有相同位置的条目在集合内相互覆盖。 (即使表中的列不同)
MSDN Docu说:“ 实现IComparable的类型必须重写Equals。重写Equals的类型也必须重写GetHashCode;否则,哈希表可能无法正常工作。”
因此,我也同时实现了这两个,但没有成功:
public class ColumnUserSetting : IComparable<ColumnUserSetting>
{
public String TableWrapperName { get; set; }
public String ColumnName { get; set; }
public Boolean Enabled { get; set; }
public int Width { get; set; }
public int Position { get; set; }
public int Compareto(ColumnUserSetting other)
{
if (other.Position == this.Position) return 0;
if (other.Position > this.Position) return -1;
return 1;
}
public override bool Equals(object obj)
{
if (!(obj is ColumnUserSetting))
return false;
ColumnUserSetting cus = (ColumnUserSetting)obj;
return (this.TableWrapperName == cus.TableWrapperName &&
this.ColumnName == cus.TableWrapperName &&
this.Enabled == cus.Enabled &&
this.Width == cus.Width &&
this.Position == cus.Position);
}
public override int GetHashCode()
{
var hashcode = 352033288;
hashcode = hashcode * -1521134295 + TableWrapperName.GetHashCode();
hashcode = hashcode * -1521134295 + ColumnName.GetHashCode();
hashcode = hashcode * -1521134295 + Enabled.GetHashCode();
hashcode = hashcode * -1521134295 + Width.GetHashCode();
hashcode = hashcode * -1521134295 + Position.GetHashCode();
return hashcode;
}
}
使SortedSet正常工作的唯一方法是处理不同表的条目,并获得Compareto
的另一个结果:
public int Compareto(ColumnUserSetting other)
{
if (this.TableWrapperName != other.TableWrapperName)
return String.Compare(this.TableWrapperName,other.TableWrapperName);
if (other.Position == this.Position) return 0;
if (other.Position > this.Position) return -1;
return 1;
}
解决方法
如果我们检查SortedSet
的{{3}},我们可以看看AddIfNotPresent()
的实现。如果已添加项目,则返回true
,如果已存在,则返回false
。
方法开始附近,我们有:
int order = 0;
while (current != null) {
order = comparer.Compare(item,current.Item);
if (order == 0) {
// We could have changed root node to red during the search process.
// We need to set it to black before we return.
root.IsRed = false;
return false;
}
因此,它仅调用Compare()
方法来查看该项是否相同。因此,对于您的班级,它只关心Position
是否相同。如果是,则不添加新项目。
我会说这是故意设计的-不是错误。
您将不得不更改您的CompareTo()
实现,以便将与Equals()
相同的所有元素进行比较。只需调用每个元素的CompareTo()
即可完成完整的排序。