.Net动态列表转换

时间:2017-12-07 09:03:21

标签: c# .net reflection casting

我必须对2个列表进行比较。问题是我不知道列表中的字段是什么类型,它们可以是int,string,decimal,enums甚至是其他对象。

我只会在运行时知道类型。我正在考虑创建一个对象列表并将它们转换为对象,问题就是让我说我​​有List<int>并且我试图将它转换为对象失败。

另一个问题是我知道只有运行时列表。所以在运行时我需要将对象类型的变量转换为列表。

如何将该对象转换为List,如何将其转换为对象列表?

更新

我有对象和反思我正在用

获得它的属性
var oldProperty = property.GetValue(old);
var newProperty = property.GetValue(new);

一旦我有了属性值,我就会看到它是一个列表,我需要比较那些2.假设oldProperty属于List类型 我试过做类似的事情:

var myOldList = (List<object>)oldProperty;

如果演员表失败

Unable to cast object of type 'System.Collections.Generic.List`1[System.Int32]' to type 'System.Collections.Generic.List`1[System.Object]'

在这里你看看我正在尝试创建的功能。请不要介意空对象(不在范围内)

 public void SetDifference(object first, object second)
    {
        var properties = first.GetType().GetProperties();
        foreach (PropertyInfo property in properties)
        {
            var oldValue = property.GetValue(first);
            var newValue = property.GetValue(second);
            if (Convert.GetTypeCode(newValue) != TypeCode.Object)
            {
                if (!oldValue.Equals(newValue))
                {
                    result.AddDifference(new PrimitiveComparison()
                    {
                        BeforeValue = oldValue.ToString(),
                        AfterValue = newValue.ToString(),
                        PropertyName = property.Name
                    });
                }
            }
            else
            {
                if (property.PropertyType.Name.Contains("List"))
                {
                    // here fails with the error from above
                    var oldList = (List<object>)oldValue; 
                    var newList = (List<object>)newValue;
                    if (oldList.Count != newList.Count)
                    {
                        result.AddDifference(new PrimitiveComparison()
                        {
                            BeforeValue = oldList.Count.ToString(),
                            AfterValue = newList.Count.ToString(),
                            PropertyName = property.Name + "Count"
                        });
                    }
                    // add the list differences
                    result.AddDifference(SetListDifference(oldList, newList);
                }
                else
                {
                    var diffrence = SetDifference(oldValue, newValue);
                    if (!diffrence.areEqual)
                    {
                        result.AddDifference(diffrence);
                    }
                }

            }
        }


}

2 个答案:

答案 0 :(得分:2)

您可以将两个值转换为IList并进行比较,例如:

static bool AreEqual(IList first, IList second) {
    if (first.Count != second.Count)
        return false;
    for (int i = 0; i < first.Count; i++) {
        if (!object.Equals(first[i], second[i]))
            return false;
    }
    return true;
}

答案 1 :(得分:1)

一旦你转换了你的列表,你可以使用linq的except方法检查列表是否有相同的元素,找到两者是否相等

double[] numbers1 = { 2.0, 2.1, 2.2, 2.3, 2.4, 2.5 };
double[] numbers2 = { 2.0, 2.1, 2.2, 2.3, 2.4, 2.5 };

IEnumerable<double> onlyInFirstSet = numbers1.Except(numbers2);
if(onlyInFirstSet.Count() ==0)
 Console.WriteLine("equal");

对于原始类型,这种方法很好但是对于用户定义的类型,您需要比较实现。

查看此博文,了解两种不同类型的列表:Difference between list of user defined types

如果你知道它将是IEnumerable类型而不是你可以尝试

 List<object> objlst = (value as IEnumerable<object>).Cast<object>
    ().ToList()

你可以这样尝试

Type t = typeof(obj);

if (t == typeof(List<int>)) {
    var lst= (List<int>)obj;

} else if (t == typeof(List<string>)) {
    var lst = (List<string>)obj;
} else if (t == typeof(List<decimal>)) {
    var lst = (List<decimal>)obj;
} 
else if (t == typeof(List<EnumName>)) {
    var lst = (List<EnumName>)obj;
}