Basically, I have two IEnumerable<FooClass>
s where each FooClass instance contains 2 properties: FirstName, LastName.
The instances on each of the enumerables is the same. 相同。 Instead, I need to check against the properties on each of the instances. I'm not sure of the most efficient way to do this, but basically I need to make sure that both lists contain similar data (not the same instance, but the same values on the properties). I don't have access to the FooClass itself to modify it.
I should say that the FooClass is a type of Attribute class, which has access to the Attribute.Match() method, so I don't need to check each properties individually.
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. }
Enumerable.SequenceEqual
will tell you if the two sequences are identical.
If FooClass
has an overridden Equals
method that compares the FirstName
and LastName
, then you should be able to write:
bool equal = List1.SequenceEqual(List2);
If FooClass
doesn't have an overridden Equals
method, then you need to create an 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();
}
}
and then you write:
var comparer = new FooComparer();
bool identical = List1.SequenceEqual(List2, comparer);
You can do in this way:
Define a custom 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());
}
}
Define an extension method to compare lists in any order and having the same number of equal elements:
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());
}
Usage example:
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());
}
Assuming that
then
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);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.