6

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;
    }
}
4
  • Why do you need to test whether it's a list of enums specifically? Enums are value types, so you could just test for value types. Commented Jul 10, 2015 at 9:33
  • @David, it is not Enums comparison, it is List of Enums comparison, which can't be compared like value types. Commented Jul 10, 2015 at 10:45
  • Then surely it's a list comparison problem? Commented Jul 10, 2015 at 10:52
  • possible duplicate of How do i get the difference in two lists in C#? Commented Jul 10, 2015 at 10:53

1 Answer 1

3

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;
    } 
Sign up to request clarification or add additional context in comments.

4 Comments

I've already try it, but didn't find the way to match those List objects. If you know then please write the generic comparison statement.
@Asim I updated my answer to include the code to compare the 2 Lists
Stephen: did you run ur code? It won't work as I already tried it.
@Asim: changed my answer, I didn't take into account you were working with object as type. Sorry about that.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.