I want to sort the list of classes and interfaces. So my logic is
if the class is not implemented interface it's higher than the interface, otherwise, it's lower
I am using the IComparer interface to sort my list. My model looks like this:
My Comparer class (if returns 1 it means y>x, 0 is x==y -1 is x>y):
public class SortedTypeComparer : IComparer<Type>
{
/// <summary>
/// Compares types
/// </summary>
public int Compare(Type x, Type y)
{
public int Compare(Type x, Type y)
{
if (y.IsAssignableFrom(x))
{
return 1;
}
else if (x.IsAssignableFrom(y))
{
return -1;
}
else if (!y.IsAssignableFrom(x) && !x.IsAssignableFrom(y) && x.IsInterface && y.IsClass)
{
return 1;
}
else if (!y.IsAssignableFrom(x) && !x.IsAssignableFrom(y) && x.IsClass && y.IsInterface)
{
return -1;
}
else
{
return 0;
}
}
}
}
I am expecting when I sort the list it should be:
IAnimal
IRunnable
Animal
ICat
Cat
Or:
IRunnable
IAnimal
Animal
ICat
Cat
Because IRunnable and IAnimal are 'equal'. Here is my usage:
var list = new List<Type>();
list.Add(typeof(IAnimal));
list.Add(typeof(IRunnable));
list.Add(typeof(ICat));
list.Add(typeof(Animal));
list.Add(typeof(Cat));
list.Sort(new SortedTypeComparer());
In this case, it is working as expected. But when I change the order of adding to list for example(put IRunnable to the end):
var list = new List<Type>();
list.Add(typeof(IAnimal));
list.Add(typeof(ICat));
list.Add(typeof(Animal));
list.Add(typeof(Cat));
list.Add(typeof(IRunnable));
list.Sort(new SortedTypeComparer());
The order is
IAnimal
Animal
ICat
IRunnable
Cat
It is not my expectation because of IRunnable>Animal. It seems when it compare Animal and ICat Animal is higher, then when it compares ICat and IRunnable it's saying "ICat == IRunnable, so Animal should be > IRunnable". How can I write the logic in the Compare method to sort my list as expected?
I do not think this is possible with a IComparer. From CompareTo
For objects A, B, and C, the following must be true:
If A.CompareTo(B) returns zero and B.CompareTo(C) returns zero, then A.CompareTo(C) is required to return zero.
So if A inherits from C and B does not inherit anything, then according to your rules compareTo should return:
A.CompareTo(B) -> 0
B.CompareTo(C) -> 0
A.CompareTo(C) -> 1
This violates the requirements of CompareTo.
An alternative would be to build an Directed acyclic graph of the hierarchy. Then you should be able to use Topological sorting to sort the graph.
Maybe answer of #JonasH more correct, but I did by fixing My comparer class. I added the following condition in my method and it is correct for most scenarios:
public class SortedTypeComparer : IComparer<Type>
{
public List<Type> AllTypes { get; set; }
public SortedTypeComparer(List<Type> types)
{
AllTypes = types;
}
/// <summary>
/// Compares types
/// </summary>
public int Compare(Type x, Type y)
{
var result = CompareIsHigherOrLower(x, y);
if (result == 0)
{
var subEntitiesOfX = AllTypes.Where(a => x.IsAssignableFrom(a) && a != x);
foreach (var subTypeOfX in subEntitiesOfX)
{
result = CompareIsHigherOrLower(subTypeOfX, y);
if (result == -1)
{
return -1;//It means SubEntity of X is higher then Y and X should be > Y
}
}
var subEntitiesOfY = AllTypes.Where(a => y.IsAssignableFrom(a) && a != y);
foreach (var subType in subEntitiesOfY)
{
result = CompareIsHigherOrLower(subType, x);
if (result == -1)
{
return 1;//It means SubEntity of Y is higher then X and Y should be > X
}
}
}
return result;
}
int CompareIsHigherOrLower(Type x, Type y)
{
if (y.IsAssignableFrom(x))
{
return 1;
}
else if (x.IsAssignableFrom(y))
{
return -1;
}
else if (!y.IsAssignableFrom(x) && !x.IsAssignableFrom(y) && x.IsInterface && y.IsClass)
{
return 1;
}
else if (!y.IsAssignableFrom(x) && !x.IsAssignableFrom(y) && x.IsClass && y.IsInterface)
{
return -1;
}
else
{
return 0;
}
}
}
Related
I've got a List<Card>, and I want to sort these cards
So, I'm looking for a method to sort them with different criterias, like their ID, their Name ...
public class Card : IComparer
{
public string ID;
public string Name;
public int CompareId(object firstCard, object secondCard)
{
Card c1 = (Card)firstCard;
Card c2 = (Card)secondCard;
return c1.Id.CompareTo(c2.Id);
}
}
But then, visual studio sent me an error :
'Card' does not implement interface member 'IComparer<Card>.Compare(Card, Card)'
You, probably, want to have your class Comparable not a Comparator
public class Card : IComparable<Card>
{
public string ID;
public string Name;
public int CompareTo(Card other)
{
if (null == other)
return 1;
// string.Compare is safe when Id is null
return string.Compare(this.Id, other.Id);
}
}
then
List<Card> myList = ...
myList.Sort();
Edit: If you want to have several criteria to choose from, you have to implement several Comparers as separated classes, e.g.
public sealed class CardByIdComparer : IComparer<Card>
{
public int Compare(Card x, Card y)
{
if (object.ReferenceEquals(x, y))
return 0;
else if (null == x)
return -1;
else if (null == y)
return 1;
else
return string.Compare(x.Id, y.Id);
}
}
and when sorting provide the required:
List<Card> myList = ...
myList.Sort(new CardByIdComparer());
Edit 2: (inspired by spender's library). If you want to combine several comparers into one (i.e. use comparer1, on tie - comparer2 etc.)
public sealed class ComparerCombined<T> : IComparer<T> {
private IComparer<T>[] m_Comparers;
public ComparerCombined(params IComparer<T>[] comparers) {
if (null == comparers)
throw new ArgumentNullException(nameof(comparers));
m_Comparers = comparers
.Select(item => item == null ? Comparer<T>.Default : item)
.Where(item => item != null)
.Distinct()
.ToArray();
}
public int Compare(T x, T y) {
if (object.ReferenceEquals(x, y))
return 0;
else if (null == x)
return -1;
else if (null == y)
return 1;
foreach (var comparer in m_Comparers) {
int result = comparer.Compare(x, y);
if (result != 0)
return result;
}
return 0;
}
}
usage:
myList.Sort(new ComparerCombined(
new CardByIdComparer(), // Sort By Id
new CardByNameComparer() // On tie (equal Id's) sort by name
));
The easiest way You can use Linq:
List<Card> objSortedList = objListObject.OrderBy(o=>o.ID).ToList();
or
List<Card> objSortedList = objListObject.OrderByDescending(o=>o.ID).ToList();
Good examples for demonstrate the concept of
List<T>.Sort(IComparer <T>) method check the link please.
IComparer<T> in this example compare method used for strings IComparer<T>
but you can use this for ID(int) too.
using System;
using System.Collections.Generic;
class GFG : IComparer<string>
{
public int Compare(string x, string y)
{
if (x == null || y == null)
{
return 0;
}
// "CompareTo()" method
return x.CompareTo(y);
}
}
public class geek
{
public static void Main()
{
List<string> list1 = new List<string>();
// list elements
list1.Add("C++");
list1.Add("Java");
list1.Add("C");
list1.Add("Python");
list1.Add("HTML");
list1.Add("CSS");
list1.Add("Scala");
list1.Add("Ruby");
list1.Add("Perl");
int range = 4;
GFG gg = new GFG();
Console.WriteLine("\nSort a range with comparer:");
// sort the list within a
// range of index 1 to 4
// where range = 4
list1.Sort(1, range, gg);
Console.WriteLine("\nBinarySearch and Insert Dart");
// Binary Search and storing
// index value to "index"
int index = list1.BinarySearch(0, range,
"Dart", gg);
if (index < 0)
{
list1.Insert(~index, "Dart");
range++;
}
}
}
You need to implement IComparer
public int Compare(Card card1, Card card2)
{
if (card1.ID > card2.ID)
return 1; //move card1 up
if (card2.ID < card1.ID)
return -1; //move card2 up
return 0; //do nothing
}
I would like to compare two arbitrary JTokens of the same type and structure (Json.Net from NewtonSoft).
static int CompareTokens(JToken x, JToken y);
// possible output: 0 / 1 / -1
The main goal is to be able use this method to sort two Json strings, so that even if in the beginning they had the same data, but in the different order, in the end these are two exactly same strings. So the sort criterion doesn't really matter, it just matters that this criterion is always the same. And each small element of data should be taken into account.
JToken can be of one of next several types: Array, Boolean, Date, Float, Guid, Integer, Null, Object, Property, String, TimeSpan, Uri. I don't take into account comparing Bytes, Comment, Constructor, None, Undefined, Raw.
It would be great to gain some idea about comparing JArrays and JObjects. That should be some recursive comparison, because JArrays may consist of other JArrays and JObjects and vice versa. Any idea would be appreciated.
But knowing about comparing simpler types would also be very helpful. I wonder rather about knowing how to convert from JToken to actual type (than about knowing how to do it logically).
JValue has IComparable implemented, but I didn't figure out how to convert simple typed JToken to JValue. Knowing about this would also be helpful.
In Linq-to-JSON, JValue represents a primitive value (string, number, boolean, and so on). It implements IComparable<JValue>, so Json.NET takes care of sorting primitive values for you.
Building off of that, you're going to need to recursively descend the two JToken object hierarchies in parallel. When you encounter the first token with a different .Net type, or different properties (if not a JValue), or with a different value (if a JValue), you need to return back the comparison value.
Keep in mind the following:
A comparison method should be reflexive, antisymmetric and transitive.
Container tokens of different .Net type need to be ordered by type in some consistent manner.
the child tokens of JArray and JConstructor are ordered.
the child tokens of JObject are not, so they need to be compared in some stable, symmetric manner. Walking both in order of property name would seem to work.
There is no obvious way to compare JRaw, so don't try, and let an exception get thrown.
The following is a prototype implementation:
public class JTokenComparer : IComparer<JToken>
{
public static JTokenComparer Instance { get { return instance; } }
static JTokenComparer instance;
static JTokenComparer()
{
instance = new JTokenComparer();
}
readonly Dictionary<Type, KeyValuePair<int, IComparer<JToken>>> dict;
JTokenComparer()
{
dict = new Dictionary<Type, KeyValuePair<int, IComparer<JToken>>>
{
// Order chosen semi-arbitrarily. Putting values first seems reasonable though.
{typeof(JValue), new KeyValuePair<int, IComparer<JToken>>(0, new JValueComparer()) },
{typeof(JProperty), new KeyValuePair<int, IComparer<JToken>>(1, new JPropertyComparer()) },
{typeof(JArray), new KeyValuePair<int, IComparer<JToken>>(2, new JArrayComparer()) },
{typeof(JObject), new KeyValuePair<int, IComparer<JToken>>(3, new JObjectComparer()) },
{typeof(JConstructor), new KeyValuePair<int, IComparer<JToken>>(4, new JConstructorComparer()) },
};
}
#region IComparer<JToken> Members
public int Compare(JToken x, JToken y)
{
if (x is JRaw || y is JRaw)
throw new InvalidOperationException("Tokens of type JRaw cannot be sorted");
if (object.ReferenceEquals(x, y))
return 0;
else if (x == null)
return -1;
else if (y == null)
return 1;
var typeData1 = dict[x.GetType()];
var typeData2 = dict[y.GetType()];
int comp;
if ((comp = typeData1.Key.CompareTo(typeData2.Key)) != 0)
return comp;
if (typeData1.Value != typeData2.Value)
throw new InvalidOperationException("inconsistent dictionary values"); // Internal error
return typeData2.Value.Compare(x, y);
}
#endregion
}
abstract class JTokenComparerBase<TJToken> : IComparer<JToken> where TJToken : JToken
{
protected TJToken CheckType(JToken item)
{
if (item != null && item.GetType() != typeof(TJToken))
throw new ArgumentException(string.Format("Actual type {0} of token \"{1}\" does not match expected type {2}", item.GetType(), item, typeof(TJToken)));
return (TJToken)item;
}
protected bool TryBaseCompare(TJToken x, TJToken y, out int comparison)
{
CheckType(x);
CheckType(y);
if (object.ReferenceEquals(x, y))
{
comparison = 0;
return true;
}
else if (x == null)
{
comparison = -1;
return true;
}
else if (y == null)
{
comparison = 1;
return true;
}
comparison = 0;
return false;
}
protected abstract int CompareDerived(TJToken x, TJToken y);
protected int TokenCompare(JToken x, JToken y)
{
var tx = CheckType(x);
var ty = CheckType(y);
int comp;
if (TryBaseCompare(tx, ty, out comp))
return comp;
return CompareDerived(tx, ty);
}
#region IComparer<JToken> Members
int IComparer<JToken>.Compare(JToken x, JToken y)
{
return TokenCompare(x, y);
}
#endregion
}
abstract class JContainerOrderedComparerBase<TJToken> : JTokenComparerBase<TJToken> where TJToken : JContainer
{
protected int CompareItemsInOrder(TJToken x, TJToken y)
{
int comp;
// Dictionary order: sort on items before number of items.
for (int i = 0, n = Math.Min(x.Count, y.Count); i < n; i++)
if ((comp = JTokenComparer.Instance.Compare(x[i], y[i])) != 0)
return comp;
if ((comp = x.Count.CompareTo(y.Count)) != 0)
return comp;
return 0;
}
}
class JPropertyComparer : JTokenComparerBase<JProperty>
{
protected override int CompareDerived(JProperty x, JProperty y)
{
int comp;
if ((comp = x.Name.CompareTo(y.Name)) != 0)
return comp;
return JTokenComparer.Instance.Compare(x.Value, y.Value);
}
}
class JObjectComparer : JTokenComparerBase<JObject>
{
protected override int CompareDerived(JObject x, JObject y)
{
int comp;
// Dictionary order: sort on items before number of items.
// Order both property sequences to preserve reflexivity.
foreach (var propertyComp in x.Properties().OrderBy(p => p.Name).Zip(y.Properties().OrderBy(p => p.Name), (xp, yp) => JTokenComparer.Instance.Compare(xp, yp)))
if (propertyComp != 0)
return propertyComp;
if ((comp = x.Count.CompareTo(y.Count)) != 0)
return comp;
return 0;
}
}
class JArrayComparer : JContainerOrderedComparerBase<JArray>
{
protected override int CompareDerived(JArray x, JArray y)
{
int comp;
if ((comp = CompareItemsInOrder(x, y)) != 0)
return comp;
return 0;
}
}
class JConstructorComparer : JContainerOrderedComparerBase<JConstructor>
{
protected override int CompareDerived(JConstructor x, JConstructor y)
{
int comp;
if ((comp = x.Name.CompareTo(y.Name)) != 0)
return comp;
if ((comp = CompareItemsInOrder(x, y)) != 0)
return comp;
return 0;
}
}
class JValueComparer : JTokenComparerBase<JValue>
{
protected override int CompareDerived(JValue x, JValue y)
{
return Comparer<JToken>.Default.Compare(x, y); // JValue implements IComparable<JValue>
}
}
Lightly tested prototype fiddle.
This could, actually, be done with less code. Not as nice, because using string comparison instead of JValue comparison.
Following is not an exact answer to my own question, but the goal is achieved.
public static JToken Normalize(this JToken token)
{
var result = token;
switch (token.Type)
{
case JTokenType.Object:
var jObject = (JObject)token;
if (jObject != null && jObject.HasValues)
{
var newObject = new JObject();
foreach (var property in jObject.Properties().OrderBy(x => x.Name).ToList())
{
var value = property.Value as JToken;
if (value != null)
{
value = Normalize(value);
}
newObject.Add(property.Name, value);
}
return newObject;
}
break;
case JTokenType.Array:
var jArray = (JArray)token;
if (jArray != null && jArray.Count > 0)
{
var normalizedArrayItems = jArray
.Select(x => Normalize(x))
.OrderBy(x => x.ToString(), StringComparer.Ordinal);
result = new JArray(normalizedArrayItems);
}
break;
default:
break;
}
return result;
}
My problem is that I always want to order a collection of objects in a certain fashion.
For example:
class foo{
public string name {get;set;}
public DateTime date {get;set;}
public int counter {get;set;}
}
...
IEnumerable<foo> dosomething(foo[] bar){
return bar.OrderBy(a=>a.name).ThenBy(a=>a.date).ThenBy(a=>a.counter);
}
The issue I have is its quite longwinded tacking-on the sort order all the time. A neat solution appears to just create a class that implements IComparer<foo>, meaning I can do:
IEnumerable<foo> dosomething(foo[] bar){
return bar.OrderBy(a=>a, new fooIComparer())
}
.
The problem is, the order method this implements is as follows
...
public int Compare(foo x, foo y){ }
Meaning it compares on a very granular basis.
The currently implementation (which will probably work, although im writing pseudocode)
public int Compare(foo x, foo y){
if (x==y)
return 0;
var order = new []{x,y}.OrderBy(a=>a.name).ThenBy(a=>a.date).ThenBy(a=>a.counter);
return (order[0] == x) ? -1 : -1;//if x is first in array it is less than y, else it is greater
}
This is not exactly efficient, can another offer a neater solution? Ideally without a Compare(x,y) method altogether?
Option 1 - The Comparer
As you're ordering by multiple conditions, you'll to check them individually within each case; for example, if x.name and y.name are equal, then you would check x.date and y.date, and so on.
public class FooComparer : IComparer<Foo>
{
public int Compare(Foo x, Foo y)
{
// nasty null checks!
if (x == null || y == null)
{
return x == y ? 0
: x == null ? -1
: 1;
}
// if the names are different, compare by name
if (!string.Equals(x.Name, y.Name))
{
return string.Compare(x.Name, y.Name);
}
// if the dates are different, compare by date
if (!DateTime.Equals(x.Date, y.Date))
{
return DateTime.Compare(x.Date, y.Date);
}
// finally compare by the counter
return x.Counter.CompareTo(y.Counter);
}
}
Option 2 - The extension method
An alternative, not so appealing approach, could be an extension method. Sadly as the TKey for each ThenBy can be different, we lose the power of generics, but can safely replace it with the type object in this case.
public static IOrderedEnumerable<T> OrderByThen<T>(this IEnumerable<T> source, Func<T, object> selector, params Func<T, object>[] thenBySelectors)
{
IOrderedEnumerable<T> ordered = source.OrderBy(selector);
foreach (Func<T, object> thenBy in thenBySelectors)
{
ordered = ordered.ThenBy(thenBy);
}
return ordered;
}
You have to implement IComparable<foo> and compare all properties:
class foo: IComparable<foo>, IComparer<foo>
{
public string name { get; set; }
public DateTime date { get; set; }
public int counter { get; set; }
public int Compare(foo x, foo y)
{
if (x == null || y == null) return int.MinValue;
if (x.name != y.name)
return StringComparer.CurrentCulture.Compare(x.name, y.name);
else if (x.date != y.date)
return x.date.CompareTo(y.date);
else if (x.counter != y.counter)
return x.counter.CompareTo(y.counter);
else
return 0;
}
public int CompareTo(foo other)
{
return Compare(this, other);
}
}
Then you can use OrderBy in this way:
var ordered = foos.OrderBy(f => f).ToList();
what's wrong with an extension method?
Why wont you simply compare your values:
int Compare(foo x, foo y)
{
if (x== null && y == null)
return 0;
else if (x == null)
return -1;
else if (y == null)
return 1;
var nameComparision = string.Compare(x.name,y.name);
if (nameComparision != 0)
return nameComparision;
var dateComparision = x.date.CompareTo(y.date);
if (dateComparision != 0)
return dateComparision;
var counterComparision = x.counter.CompareTo(y.counter);
return counterComparision;
}
I want to write a custom comparer for a SortedDictionary, where keys are sorted based on their type. Is this possible?
public class StateBase
{
// This is a base class I have to inherit from
}
SortedDictionary<StateBase, int> _stateDictionary =
new SortedDictionary<StateBase, int>(new StateComparer());
class StateComparer : IComparer<StateBase>
{
public int Compare(StateBase a, StateBase b)
{
// I'd like to sort these based on their type
// I don't particularly care what order they are in, I just want them
// to be sorted.
}
}
Sure, why not? Note that we must be talking about reference-types for this to apply, so something like:
public class TypeComparer<T> : IComparer<T>, IEqualityComparer<T> where T : class
{
public static readonly TypeComparer<T> Singleton= new TypeComparer<T>();
private TypeComparer(){}
bool IEqualityComparer<T>.Equals(T x, T y)
{
if (ReferenceEquals(x, y)) return true;
if (x == null || y == null) return false;
Type xType = x.GetType(), yType = y.GetType();
return xType == yType && EqualityComparer<T>.Default.Equals(x, y);
}
int IEqualityComparer<T>.GetHashCode(T x)
{
if (x == null) return 0;
return -17*x.GetType().GetHashCode() + x.GetHashCode();
}
int IComparer<T>.Compare(T x, T y)
{
if(x==null) return y == null ? 0 : -1;
if (y == null) return 1;
Type xType = x.GetType(), yType = y.GetType();
int delta = xType == yType ? 0 : string.Compare(
xType.FullName, yType.FullName);
if (delta == 0) delta = Comparer<T>.Default.Compare(x, y);
return delta;
}
}
You can. If your comparer implements IComparer<T>, it can be passed to a new SortedDictionary instance by the corresponding constructor overload.
The Compare method then somehow decides what item is greater or lower. It is the place where you can implement your compare-by-type logic.
Here is an example to compare Type instances based on their name:
public class TypeComparer : IComparer<Type>
{
public int Compare(Type x, Type y)
{
if(x != null && y != null)
return x.FullName.CompareTo(y.FullName);
else if(x != null)
return x.FullName.CompareTo(null);
else if(y != null)
return y.FullName.CompareTo(null);
else
return 0;
}
}
I have the following class:
public class DocumentCompare
{
public string Customer;
public string Filename;
public string Reference;
public DateTime? Date;
public override bool Equals(object obj)
{
if (obj == null)
return false;
DocumentCompare doc = obj as DocumentCompare;
if ((Object)doc == null)
return false;
return (doc.Customer == Customer) && (doc.Date == Date) && (doc.Filename == Filename) && (doc.Reference == Reference);
}
public bool Equals(DocumentCompare doc)
{
if ((object)doc == null)
return false;
return (doc.Customer == Customer) && (doc.Date == Date) && (doc.Filename == Filename) && (doc.Reference == Reference);
}
public override int GetHashCode()
{
return string.Format("{0}_{1}_{2}_{3}",Customer,Filename,Reference,(Date == null ? "" : Date.Value.ToString())).GetHashCode();
}
}
I will be retrieving 2 lists of this class - what I want to do is to compare the two, and get ones that don't exist in both. So if an item exists in x list but not in y, I want to perform an action for the items in this list. If an item exists in y list but not in x, I want to do a different action.
How would I do this? Using LINQ I guess!
EDIT: Performance is not much of an issue - this will only be run once
It sounds like you just want Except:
foreach (var newItem in firstList.Except(secondList))
{
...
}
As an aside:
That's not a terribly nice way of generating a hash code - search for other questions here.
Delegate from Equals(object) to Equals(DocumentCompare) to avoid repetitive logic
Mutable types aren't great candidates for equality comparisons (in particular, one you've used a value as a key in a dictionary, if you change the equality-sensitive components you won't be able to find the key again)
Even if you do want it to be mutable, properties are better for encapsulation than public fields
I would either seal the type or check whether the two objects are exactly the same type, as otherwise you could end up with asymmetric equality
here is the code:
var elementsMissingFromFirstList = firstList.Except(secondList).ToList();
var elementsMissingInSecondList = secondList.Except(firstList).ToList();
now you can perform your actions on these missing elements :)
You can use this method to compare objects of two different Lists. exmp: List and List x and y = DocumentCompare,
public static bool EqualsObject<T>(this T t1, T t2) where T : class
{
var p1 = t1.GetType().Fields();
var p2 = t2.GetType().Fields();
for (int j = 0; j < p1.Length; j++)
{
var x = p1[j].GetValue(t1, null);
var y = p2[j].GetValue(t2, null);
if (x == null && y == null)
continue;
if (x != null && y == null)
return false;
if (x == null)
return false;
if (!x.Equals(y))
{
return false;
}
}
return true;
}
This method will show the difference between these two lists.
public static List<T> DifferentObjects<T>(List<T> t, List<T> t2) where T : class
{
var diff = new List<T>();
if (t != null && t2 != null)
{
foreach (T t1 in t)
{
var state = false;
foreach (T t3 in t2.Where(t3 => EqualsObject(t1,t3)))
{
state = true;
}
if (!state)
{
diff.Add(t1);
}
}
}
return diff;
}
you can use code this way
var t = new List<DocumentCompare>();
var t2 = new List<DocumentCompare>();
t.Add(new DocumentCompare{Customer = "x"});
t.Add(new DocumentCompare{Customer = "y"});
t.Add(new DocumentCompare{Customer = "z"});
t2.Add(new DocumentCompare { Customer = "t" });
t2.Add(new DocumentCompare { Customer = "y" });
t2.Add(new DocumentCompare { Customer = "z" });
var list = DifferentObjects(t, t2);
var list2 = DifferentObjects(t2, t);
you used fields (Customer,FileName etc..) in your class, so that GetType().Fields(); is used in EqualsObject method. if you use property , you should use GetType().Properties(); in EqualsObject method.