Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compare two List<enum> objects in C#

Tags:

c#

list

enums

I've two dictionaries like:

Dictionary<string, object> dict1 = new Dictionary<string, object>();
Dictionary<string, object> dict2 = new Dictionary<string, object>();

I want to compare them where few entries are List<Enum>, how can I compare these List<Enum> objects. Please see following sample code:

enum Days { Monday, Tuesday, Wednesday }
enum Colors { Red, Green, Blue }
enum Cars { Acura, BMW, Ford }

Populating dictionaries:

List<Days> lst1 = new List<Days>();
List<Days> lst2 = new List<Days>();

lst1.Add(Days.Monday); lst1.Add(Days.Tuesday); 
lst2.Add(Days.Monday); lst2.Add(Days.Tuesday);

dict1.Add("DayEnum", lst1);
dict2.Add("DayEnum", lst2);

foreach (KeyValuePair<string, object> entry in dict1)
{
    var t1 = dict1[entry.Key];
    var t2 = dict2[entry.Key];

    if (dict1[entry.Key].GetType().IsGenericType && Compare(dict1[entry.Key], dict2[entry.Key]))
    {
                // List elements matches...
    } 
    else if (dict1[entry.Key].Equals(dict2[entry.Key]))
    {
                // Other elements matches...
    }
}

It doesn't match unless I provide the exact Enum i.e. IEnumerable<Days> but I need a generic code to work for any Enum.

So far I found following way to compare, but I need a generic comparision statement as I don't know all Enums:

private static bool Compare<T>(T t1, T t2)
{
    if (t1 is IEnumerable<T>)
    {
        return (t1 as IEnumerable<T>).SequenceEqual(t2 as IEnumerable<T>);
    }
    else
    {
        Type[] genericTypes = t1.GetType().GetGenericArguments();
        if (genericTypes.Length > 0 && genericTypes[0].IsEnum)
        {
            if (genericTypes[0] == typeof(Days))
            {
                return (t1 as IEnumerable<Days>).SequenceEqual(t2 as IEnumerable<Days>);
            }
            else if (genericTypes[0] == typeof(Colors))
            {
                return (t1 as IEnumerable<Colors>).SequenceEqual(t2 as IEnumerable<Colors>);
            }
        }

        return false;
    }
}
like image 582
Asim Avatar asked Oct 20 '22 07:10

Asim


1 Answers

First get the type of the generic arguments with Type.GetGenericArguments(), then you can call IsEnum on that.

So, something like

var listType = dict1[entry.Key].GetType();
if (listType.IsGenericType)
{
   var typeArguments = listType.GetGenericArguments();
   //if you only have List<T> in there, you can pull the first one
   var genericType = typeArguments[0];
   if (genericType.IsEnum) {
        // List elements matches...
   }                
} 

In answer to your comment, if you want to compare the 2 Lists, you can do the following. Because you have the lists as object in a dictionary, you're better of creating your own method to check whether each element is the same as the element in the other list, because for SequenceEqual you have to know the type.

        var listType = dict1[entry.Key].GetType();
        var secondListType = dict2[entry.Key].GetType();
        if (listType.IsGenericType && secondListType.IsGenericType)
        {
            //if you only have List<T> in there, you can pull the first one
            var genericType = listType.GetGenericArguments()[0];
            var secondGenericType = secondListType.GetGenericArguments()[0];
            if (genericType.IsEnum && genericType == secondGenericType && AreEqual((Ilist)dict1[entry.Key],(Ilist)dict2[entry.Key]))
            {                    
                // List elements matches...
            }
        }

    public bool AreEqual(IList first, IList second)
    {
        if (first.Count != second.Count)
        {
            return false;
        }

        for (var elementCounter = 0; elementCounter < first.Count; elementCounter++)
        {
            if (!first[elementCounter].Equals(second[elementCounter]))
            {
                return false;
            }
        }
        return true;
    } 
like image 65
Stephen Avatar answered Oct 30 '22 13:10

Stephen