我对SortedSet的行为有些疑惑,请看下面的例子:
public class Blah { public double Value { get; private set; } public Blah(double value) { Value = value; } } public class BlahComparer : Comparer<Blah> { public override int Compare(Blah x,Blah y) { return Comparer<double>.Default.Compare(x.Value,y.Value); } } public static void main() { var blahs = new List<Blah> {new Blah(1),new Blah(2),new Blah(3),new Blah(2)} //contains all 4 entries var set = new HashSet<Blah>(blahs); //contains only Blah(1),Blah(2),Blah(3) var sortedset = new SortedSet<Blah>(blahs,new BlahComparer()); }
如果Compare(x,y)返回0,则SortedSet将丢弃条目.可以防止这种情况,因为如果Equals()返回true,则SortedSet的行为类似于HashSet,并丢弃条目.
解决方法
如果在值相等并且Compare方法返回0时提供备用比较,则可以执行此操作.在大多数情况下,这可能只是推迟问题而不是解决问题.正如其他人所指出的那样,SortedSet丢弃了重复项,当您提供自定义比较器时,它使用它来确定重复性.
static void Main(string[] args) { var blahs = new List<Blah> { new Blah(1,0),new Blah(2,1),new Blah(3,2),3) }; blahs.Add(blahs[0]); //contains all 4 entries var set = new HashSet<Blah>(blahs); //contains all 4 entries var sortedset = new SortedSet<Blah>(blahs,new BlahComparer()); } } public class Blah { public double Value { get; private set; } public Blah(double value,int index) { Value = value; Index = index; } public int Index { get; private set; } public override string ToString() { return Value.ToString(); } } public class BlahComparer : Comparer<Blah> { public override int Compare(Blah x,Blah y) { // needs null checks var referenceEquals = ReferenceEquals(x,y); if (referenceEquals) { return 0; } var compare = Comparer<double>.Default.Compare(x.Value,y.Value); if (compare == 0) { compare = Comparer<int>.Default.Compare(x.Index,y.Index); } return compare; } }