基本上,我有两个IEnumerable<FooClass>
,其中每个FooClass实例包含2个属性:FirstName,LastName。
每个可枚举的实例 NOT 相同。相反,我需要检查每个实例上的属性。我不确定最有效的方法,但基本上我需要确保两个列表包含相似的数据(不是相同的实例,但属性上的值相同)。我无法访问FooClass本身来修改它。
我应该说FooClass是一种Attribute类,可以访问Attribute.Match()方法,所以我不需要单独检查每个属性。
<小时/> 根据评论,我更新了问题更具体,稍微改了一下......这就是我到目前为止所做的:
public void Foo()
{
var info = typeof(MyClass);
var attributes = info.GetCustomAttributes(typeof(FooAttribute), false) as IEnumerable<FooAttribute>;
var validateAttributeList = new Collection<FooAttribute>
{
new FooAttribute(typeof(int), typeof(double));
new FooAttribute(typeof(int), typeof(single));
};
//Make sure that the each item in validateAttributeList is contained in
//the attributes list (additional items in the attributes list don't matter).
//I know I can use the Attribute.Match(obj) to compare.
}
答案 0 :(得分:3)
Enumerable.SequenceEqual
会告诉您两个序列是否相同。
如果FooClass
有一个被覆盖的Equals
方法,可以比较FirstName
和LastName
,那么您应该能够写一下:
bool equal = List1.SequenceEqual(List2);
如果FooClass
没有覆盖Equals
方法,则需要创建IEqualityComparer<FooClass>
:
class FooComparer: IEqualityComparer<FooClass>
{
public bool Equals(FooClass f1, FooClass f2)
{
return (f1.FirstName == f2.FirstName) && (f1.LastName == f2.LastName);
}
public int GetHashCode()
{
return FirstName.GetHashCode() ^ LastName.GetHashCode();
}
}
然后你写:
var comparer = new FooComparer();
bool identical = List1.SequenceEqual(List2, comparer);
答案 1 :(得分:2)
你可以这样做:
定义自定义 IEqualityComparer<FooAttribute>
:
class FooAttributeComparer : IEqualityComparer<FooAttribute>
{
public bool Equals(FooAttribute x, FooAttribute y)
{
return x.Match(y);
}
public int GetHashCode(FooAttribute obj)
{
return 0;
// This makes lookups complexity O(n) but it could be reasonable for small lists
// or if you're not sure about GetHashCode() implementation to do.
// If you want more speed you could return e.g. :
// return obj.Field1.GetHashCode() ^ (17 * obj.Field2.GetHashCode());
}
}
定义一种扩展方法,以任意顺序比较列表并具有相同数量的相等元素:
public static bool ListContentIsEqualInAnyOrder<T>(
this IEnumerable<T> list1, IEnumerable<T> list2, IEqualityComparer<T> comparer)
{
var lookup1 = list1.ToLookup(x => x, comparer);
var lookup2 = list2.ToLookup(x => x, comparer);
if (lookup1.Count != lookup2.Count)
return false;
return lookup1.All(el1 => lookup2.Contains(el1.Key) &&
lookup2[el1.Key].Count() == el1.Count());
}
用法示例:
static void Main(string[] args)
{
List<FooAttribute> attrs = new List<FooAttribute>
{
new FooAttribute(typeof(int), typeof(double)),
new FooAttribute(typeof(int), typeof(double)),
new FooAttribute(typeof(bool), typeof(float)),
new FooAttribute(typeof(uint), typeof(string)),
};
List<FooAttribute> attrs2 = new List<FooAttribute>
{
new FooAttribute(typeof(uint), typeof(string)),
new FooAttribute(typeof(int), typeof(double)),
new FooAttribute(typeof(int), typeof(double)),
new FooAttribute(typeof(bool), typeof(float)),
};
// this returns true
var listEqual1 = attrs.ListContentIsEqualInAnyOrder(attrs2, new FooAttributeComparer());
// this returns false
attrs2.RemoveAt(1);
var listEqual2 = attrs.ListContentIsEqualInAnyOrder(attrs2, new FooAttributeComparer());
}
答案 2 :(得分:0)
假设
然后
var setA = new HashSet<String>(
firstEnumerable.Select(i => i.FirstName.ToUpper() + "!" + i.LastName.ToUpper()));
var setB = new HashSet<String>(
secondEnumerable.Select(i => i.FirstName.ToUpper() + "!" + i.LastName.ToUpper()));
return setA.SetEquals(setB);