【发布时间】:2020-09-02 16:04:17
【问题描述】:
我将 users 表列配置存储在一个简单的类中:
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 文档说:“实现 IComparable 的类型必须覆盖 Equals。覆盖 Equals 的类型也必须覆盖 GetHashCode;否则,Hashtable 可能无法正常工作。”
所以,我也实现了这两个,但没有成功:
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;
}
这是错误还是功能?
【问题讨论】:
-
你说条目是覆盖,但是比较为 0 时的动作不是覆盖?
-
是的,没有仔细研究,只是注意到骗子不见了。但事实上,之后“未添加”重复项,保留添加的第一个条目。 (根据相同的 CompareTo-Result 重复,即使它们不相等)
标签: c# equals compareto icomparable