问题
Hi i have an issue while doing xoring between objects in c#. Suppose i have a class having below properties -
public string UserName { get; set; }
public bool IsUserEmployed { get; set; }
public bool IsUserValid { get; set; }`
I have 2 lists of this classes:
List<Class1> List1 = new List<Class1>();
List<Class1> List2 = new List<Class1>();
I tried the basic xoring as follows:
FinalList.AddRange(List1.Except(List2));
FinalList.AddRange(List2.Except(List1));`
But i didnt got the results in the FinalList
as xor.
I want to perform xor on the List1
and List2
that could compare all the 3 properties in the objects in both the list and give me a 3rd list. Kindly Help.
回答1:
This is a solution scratched together in LinqPad. I have created a custom IEqualityComparerm, which can be reused at will. To use this comparer I am passing 2 arguments to the Except
method: the second list and the comparer.
void Main()
{
List<CustomObject> List1 = new List<CustomObject>()
{
new CustomObject() {UserName ="1", IsUserEmployed = true, IsUserValid = false},
new CustomObject() {UserName ="2", IsUserEmployed = true, IsUserValid = false},
new CustomObject() {UserName ="3", IsUserEmployed = true, IsUserValid = false},
new CustomObject() {UserName ="4", IsUserEmployed = true, IsUserValid = false}
};
List<CustomObject> List2 = new List<CustomObject>()
{
new CustomObject() {UserName ="2", IsUserEmployed = true, IsUserValid = false},
new CustomObject() {UserName ="3", IsUserEmployed = true, IsUserValid = false},
};
IEqualityComparer<CustomObject> CustomComparer = new CustomObjectEqualityComparer<CustomObject>();
var xor = List1.Except(List2, CustomComparer).ToList().Dump();
}
public class CustomObject
{
public string UserName { get; set; }
public bool IsUserEmployed { get; set; }
public bool IsUserValid { get; set; }
}
public class CustomObjectEqualityComparer<T> : IEqualityComparer<CustomObject>
{
public bool Equals(CustomObject t1, CustomObject t2)
{
if(t1.IsUserEmployed == t2.IsUserEmployed &&
t1.IsUserValid ==t2.IsUserValid &&
t1.UserName == t2.UserName)
{
return true;
}
return false;
}
public int GetHashCode(CustomObject _obj)
{
return _obj.IsUserEmployed.GetHashCode() + _obj.IsUserEmployed.GetHashCode() + _obj.IsUserValid.GetHashCode();
}
}
public static class IEnumerableExtensions
{
public static void ForEach<T>(this IEnumerable<T> source, Action<T> action)
{
foreach (T item in source)
action(item);
}
}
As a small note: This code does not check for null or other possible errors.
回答2:
You need to override the Equals method of your Class1
.
Why? Because right now it is comparing for instances which I guess in your case will always return false.
public override bool Equals(Object obj)
{
Class cs = (MyClass)obj;
return UserName == cs.UserName &&
IsUserEmployed = cs.IsUserEmployed &&
IsUserValid == cs.IsUserValid;
}
**You need to put some checks where obj is not null.
回答3:
Alternative implementation of fast xor IList
collections
public static IList<T> ExclusiveOr<T>([NotNull]this IList<T> @this, IList<T> a)
{
a = a ?? new T[]{};
ISet<T> set = new HashSet<T>(@this);
foreach (T current in a)
{
if (set.Contains(current))
{
set.Remove(current);
}
else
{
set.Add(current);
}
}
return set.ToList();
}
回答4:
There is an extension for XOR, left XOR or right XOR between two lists : https://stackoverflow.com/a/45480272/2546739
You can use it with an IEqualityComparer
or not, at your choice.
来源:https://stackoverflow.com/questions/24198649/xor-of-list-of-objects-in-c-sharp