我试图派生两个ObservableCollections的并集,并且union中的项不是唯一的。
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq;
namespace ObservableCollectionUnion
{
class Program
{
class Option { public string Code; }
static void Main(string[] args)
{
Option[] opts1 = {
new Option { Code = "1" },
new Option { Code = "2" },
};
Option[] opts2 = {
new Option { Code = "2" },
new Option { Code = "3" },
};
ObservableCollection<Option> obsOpts1 = new ObservableCollection<Option>(opts1);
ObservableCollection<Option> obsOpts2 = new ObservableCollection<Option>(opts2);
ObservableCollection<Option> obsOptsBoth = new ObservableCollection<Option>(obsOpts1.Union(obsOpts2));
foreach (Option opt in obsOptsBoth) {
Debug.WriteLine(opt.Code);
}
}
}
}
输出是:
1
2
2
3
我如何获得1,2,3?我试过传入IComparer或IEqualityComparer,但是我得到了错误
Error CS1929 'ObservableCollection<Program.Option>' does not contain a definition for 'Union' and the best extension method overload 'Queryable.Union<Program.Option>(IQueryable<Program.Option>, IEnumerable<Program.Option>, IEqualityComparer<Program.Option>)' requires a receiver of type 'IQueryable<Program.Option>'
以下是我正在尝试做的事情:
using System;
using System.Collections;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq;
namespace ObservableCollectionUnion
{
class Program
{
class Option { public string Code; }
class OptionComparer : IEqualityComparer
{
public new bool Equals(object x, object y)
{
return Convert.ToInt32(((Option)x).Code) == Convert.ToInt32(((Option)y).Code);
}
public int GetHashCode(object obj)
{
return ((Option)obj).Code.GetHashCode();
}
}
static void Main(string[] args)
{
Option[] opts1 = {
new Option { Code = "1" },
new Option { Code = "2" },
};
Option[] opts2 = {
new Option { Code = "2" },
new Option { Code = "3" },
};
ObservableCollection<Option> obsOpts1 = new ObservableCollection<Option>(opts1);
ObservableCollection<Option> obsOpts2 = new ObservableCollection<Option>(opts2);
ObservableCollection<Option> obsOptsBoth = new ObservableCollection<Option>(obsOpts1.Union(obsOpts2, new OptionComparer()));
foreach (Option opt in obsOptsBoth) {
Debug.WriteLine(opt.Code);
}
}
}
}
有趣的是,我正在关注intellisense告诉我的内容。它说ObservableCollection.Union有一个签名
public static IEnumerable<TSource> Union<TSource>(this IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer);
它不会返回重复项。如果你做了类似的事情
var commonOption = new Option { Code = "2" }
并在可观察的集合中使用它,它将按预期工作。默认情况下,只有当它们是同一个实例时,类才相等。如果你想要其他类型的相等,你可以通过重写相等运算符来定义它。