通用解决方案,用于比较仅在运行时已知的两个通用列表和类型

时间:2017-05-11 11:34:01

标签: c# .net generics

我已经阅读了很多帖子,其中回答了这个问题。但问题是我有两个通用的列表,其类型将在运行时知道,其次我需要将一个列表的所有列与其他列表的所有列进行比较。唯一统一的是两个列表的类型相同。

对于不同类型的列表,此操作必须完成27次。

所以我需要一个通用的解决方案来比较这两个列表。如需更多详细信息,请告知。但这对我很重要。

 private void CompareTwoObjects(IList dataFromExcel, IList dataFromTable)
        {
            foreach (var objExcel in dataFromExcel)
            {

            }
        }

希望完全像这样。我不确定。可能这可以帮助您获得所需的确切内容。

2 个答案:

答案 0 :(得分:1)

您最简单的解决方案是在27种不同类型上实施IEquatable<T>。然后,您可以使用常规的等号运算符(dataFromExcel.Equals(dataFromTable)dataFromExcel == dataFromTable。但是,如果您需要在此过程中对值执行任何操作,则还有其他选项。

使用this answer中的想法,您无需使用反射即可获得此功能。利用Newtonsoft JSON.NET库来完成&#34;繁重的工作#34;为你,并保持你的代码可读。

您要做的一件事是将每个列表的类型限制为相同的类型。你的方法看起来像这样:

private bool CompareTwoObjects<T>(T one, T two)
{
    var json1 = JObject.FromObject(one);
    var json2 = JObject.FromObject(two);

    foreach (JProperty prop1 in json1.Properties())
    {
        var prop2 = json2.Properties().First(p => p.Name == prop1.Name);

        if (prop1.Value != prop2.Value)
        {
            return false;
        }
    }

    return true;
}

在评论中看到您要比较每个系列的集合,您仍然可以使用这两个选项。

IEquatable<T>方法:

var allAreEqual = dataFromExcel.All(one => dataFromTable.Any(two => one == two));

自定义方法:

var allAreEqual = dataFromExcel(one => dataFromTable.Any(two => CompareTwoObjects(one, two));

我确定你可以在这里做一些优化以减少N因子,但这会指向正确的方向。

答案 1 :(得分:0)

我不确定这个解决方案(因为性能和可序列化类型),但可能您可以将集合序列化为JSON(例如)并比较字符串。请注意,在这种情况下,集合由不同类型关闭 List<TypeForCompare1>()List<TypeForCompare2>()可以与当前实施相同。然而,它很容易尝试,也许对你来说已经足够了。

class Type1
{
    public int Prop1 { get; set; }
    public string Prop2 { get; set; }
}

class TypeForCompare1
{
    public Type1 Prop1 { get; set; }
    public double Prop2 { get; set; }
}

class TypeForCompare2
{
    public Type1 Prop1 { get; set; }
    public double Prop2 { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        var List1 = new List<int>() { 1, 2 };
        var List2 = new List<int>() { 1, 2, 3 };

        var List3 = new List<TypeForCompare1>() {
            new TypeForCompare1() { Prop1 = new Type1 { Prop1 = 1, Prop2 = "test" }, Prop2 = 1.23 },
        };

        var List4 = new List<TypeForCompare2>() {
            new TypeForCompare2() { Prop1 = new Type1 { Prop1 = 1, Prop2 = "test" }, Prop2 = 1.23 },
        };

        Console.WriteLine(CompareTwoObjects(List1, List2));
        Console.WriteLine(CompareTwoObjects(List3, List4));

        Console.ReadLine();
    }

    static bool CompareTwoObjects(IList obj1, IList obj2)
    {
        var JsonObj1 = new JavaScriptSerializer().Serialize(obj1);
        var JsonObj2 = new JavaScriptSerializer().Serialize(obj2);
        return JsonObj1 == JsonObj2;
    }
}