【问题标题】:Compare two List<enum> objects in C#比较 C# 中的两个 List<enum> 对象
【发布时间】:2015-07-10 09:15:36
【问题描述】:

我有两个字典,例如:

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

我想比较它们,其中很少有条目是List&lt;Enum&gt;,我该如何比较这些List&lt;Enum&gt; 对象。请看下面的示例代码:

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

填充字典:

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...
    }
}

除非我提供确切的枚举,即IEnumerable&lt;Days&gt;,否则它不匹配,但我需要一个通用代码来为任何枚举工作。

到目前为止,我找到了以下比较方法,但我需要一个通用的比较语句,因为我不知道所有枚举:

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;
    }
}

【问题讨论】:

  • 为什么要专门测试它是否是枚举列表?枚举是值类型,因此您可以只测试值类型。
  • @David,不是Enums比较,是List of Enums比较,不能像值类型一样比较。
  • 那肯定是列表比较问题?

标签: c# list enums


【解决方案1】:

首先用Type.GetGenericArguments()获取泛型参数的类型,然后你可以调用IsEnum

所以,像

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...
   }                
} 

在回答您的评论时,如果您想比较两个列表,您可以执行以下操作。因为您将列表作为字典中的对象,所以最好创建自己的方法来检查每个元素是否与另一个列表中的元素相同,因为对于 SequenceEqual,您必须知道类型。

        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;
    } 

【讨论】:

  • 我已经尝试过了,但没有找到匹配那些 List 对象的方法。如果你知道,请写出通用比较语句。
  • @Asim 我更新了我的答案以包含比较两个列表的代码
  • 斯蒂芬:你运行你的代码了吗?它不会工作,因为我已经尝试过了。
  • @Asim:更改了我的答案,我没有考虑到您使用 object 作为类型。对此感到抱歉。
猜你喜欢
  • 1970-01-01
  • 2013-04-18
  • 2018-02-26
  • 1970-01-01
  • 2023-03-07
  • 2013-12-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多