Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/300.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用反射在字典上调用Enumerable.Except(IEnumerable)_C#_.net_.net Core_System.reflection - Fatal编程技术网

C# 使用反射在字典上调用Enumerable.Except(IEnumerable)

C# 使用反射在字典上调用Enumerable.Except(IEnumerable),c#,.net,.net-core,system.reflection,C#,.net,.net Core,System.reflection,我尝试使用反射来比较相同类型的对象的属性 问题是,对于引用类型==,我尝试使用反射来比较IEnumerable的值。为此,我尝试调用可枚举。除了(t) 它适用于列表,但不适用于词典: 无法强制转换类型为的对象 'd_u571[System.Collections.Generic.KeyValuePair2[System.String,System.String]] 输入'System.Collections.Generic.IEnumerable'1[System.Object]' 此代码存在以

我尝试使用反射来比较相同类型的对象的属性

问题是,对于引用类型
==
,我尝试使用反射来比较IEnumerable的值。为此,我尝试调用
可枚举。除了(t)

适用于
列表
,但不适用于
词典

无法强制转换类型为的对象 'd_u57
1[System.Collections.Generic.KeyValuePair
2[System.String,System.String]] 输入'System.Collections.Generic.IEnumerable'1[System.Object]'

此代码存在以下问题:

var typeKeyValuePair = typeof(KeyValuePair<,>);                      
                   Type[] typeArgs = { args[0], args[1] };

                    exceptMethods = typeof(Enumerable)
                        .GetMethods(BindingFlags.Static | BindingFlags.Public)
                        .FirstOrDefault(mi => mi.Name == "Except")
                        ?.MakeGenericMethod(typeKeyValuePair.MakeGenericType(typeArgs));
var-typeKeyValuePair=typeof(KeyValuePair);
类型[]typeArgs={args[0],args[1]};
exceptMethods=typeof(可枚举)
.GetMethods(BindingFlags.Static | BindingFlags.Public)
.FirstOrDefault(mi=>mi.Name==“除外”)
?.MakeGenericMethod(typeKeyValuePair.MakeGenericType(typeArgs));
信息的完整代码

 public static List<Variance> DetailedCompare<T>(this T val1, T val2)
    {
        List<Variance> variances = new List<Variance>();

        PropertyInfo[] propertyInfo = val1.GetType().GetProperties();
        foreach (PropertyInfo p in propertyInfo)
        {
            Variance v = new Variance();
            v.Prop = p.Name;
            v.valA = p.GetValue(val1);
            v.valB = p.GetValue(val2);

            switch (v.valA)
            {
                case null when v.valB == null:
                    continue;
                case null:
                    variances.Add(v);
                    continue;
            }

            if (v.valA.Equals(v.valB)) continue;


            if (typeof(IEnumerable).IsAssignableFrom(p.PropertyType))
            {
                //string
                if (p.PropertyType == typeof(string))
                {
                    variances.Add(v);
                    continue;
                }

                var args = p.PropertyType.GetGenericArguments();
                MethodInfo exceptMethods = null;

                if (args.Length == 2) //dictionaries
                {
                    variances.Add(v); // add to difference while not able to compare
                    /*
                   var typeKeyValuePair = typeof(KeyValuePair<,>);                      
                   Type[] typeArgs = { args[0], args[1] };

                    exceptMethods = typeof(Enumerable)
                        .GetMethods(BindingFlags.Static | BindingFlags.Public)
                        .FirstOrDefault(mi => mi.Name == "Except")
                        ?.MakeGenericMethod(typeKeyValuePair.MakeGenericType(typeArgs));*/
                }

                else if (args.Length == 1)//lists
                {
                    exceptMethods = typeof(Enumerable)
                        .GetMethods(BindingFlags.Static | BindingFlags.Public)
                        .FirstOrDefault(mi => mi.Name == "Except")
                        ?.MakeGenericMethod(p.PropertyType.GetGenericArguments().FirstOrDefault());
                }

                else//not 
                {
                    variances.Add(v);
                }

                if (exceptMethods != null)
                {
                    try
                    {
                        var res1 = (IEnumerable<object>)exceptMethods.Invoke(v.valA, new[] { v.valA, v.valB });
                        var res2 = (IEnumerable<object>)exceptMethods.Invoke(v.valB, new[] { v.valB, v.valA });
                        if (res1.Any() != res2.Any()) variances.Add(v);
                    }
                    catch (Exception ex)
                    {

                    }

                    /* if (v.valA.Except(v.valB).Any() || v.valB.Except(v.valA).Any())
                    {
                        variances.Add(v);
                    }*/
                }
            }
        }
        return variances;
    }
}

class Variance
{
    public string Prop { get; set; }
    public object valA { get; set; }
    public object valB { get; set; }
}
公共静态列表DetailedCompare(此T值1,T值2)
{
列表差异=新列表();
PropertyInfo[]PropertyInfo=val1.GetType().GetProperties();
foreach(PropertyInfo中的PropertyInfo p)
{
方差v=新方差();
v、 Prop=p.名称;
v、 valA=p.GetValue(val1);
v、 valB=p.GetValue(val2);
开关(v.valA)
{
当v.valB==null时为空:
继续;
大小写为空:
差异。添加(v);
继续;
}
如果(v.valA等于(v.valB))继续;
if(typeof(IEnumerable).IsAssignableFrom(p.PropertyType))
{
//串
if(p.PropertyType==typeof(string))
{
差异。添加(v);
继续;
}
var args=p.PropertyType.GetGenericArguments();
MethodInfo exceptMethods=null;
if(args.Length==2)//字典
{
差异。添加(v);//添加到差异中,但无法进行比较
/*
var typeKeyValuePair=类型(KeyValuePair);
类型[]typeArgs={args[0],args[1]};
exceptMethods=typeof(可枚举)
.GetMethods(BindingFlags.Static | BindingFlags.Public)
.FirstOrDefault(mi=>mi.Name==“除外”)
?.MakeGenericMethod(typeKeyValuePair.MakeGenericType(typeArgs))*/
}
else if(args.Length==1)//列表
{
exceptMethods=typeof(可枚举)
.GetMethods(BindingFlags.Static | BindingFlags.Public)
.FirstOrDefault(mi=>mi.Name==“除外”)
?.MakeGenericMethod(p.PropertyType.GetGenericArguments().FirstOrDefault());
}
否则//
{
差异。添加(v);
}
if(exceptMethods!=null)
{
尝试
{
var res1=(IEnumerable)exceptMethods.Invoke(v.valA,new[]{v.valA,v.valB});
var res2=(IEnumerable)exceptMethods.Invoke(v.valB,new[]{v.valB,v.valA});
如果(res1.Any()!=res2.Any())差异。添加(v);
}
捕获(例外情况除外)
{
}
/*if(v.valA.Except(v.valB.Any()| | v.valB.Except(v.valA.Any())
{
差异。添加(v);
}*/
}
}
}
回报差异;
}
}
阶级差异
{
公共字符串属性{get;set;}
公共对象valA{get;set;}
公共对象valB{get;set;}
}

<代码> > p>我认为您可以考虑将其转换为泛型iQueDaby,然后将其装箱为具有<代码>的对象。OfType < /Cord>重载函数。完整的代码如下所示:

    void TestFunction()
    {


        var v1 = new { yes = "asdf", no = "as", ar = new List<int>() { 1, 2, 3 }, dict = new Dictionary<object, object>() { { 1, 1 }, { 2, 2 } } };
        var v2 = new { yes = "asdf", no = "fd", ar = new List<int>() { 1, 2, 3 }, dict = new Dictionary<object, object>() { { 1, 1 }, { 2, 2 } } };

        var differences = DetailedCompare(v1, v2);

    }

    public static List<Variance> DetailedCompare<T>(T val1, T val2)
    {
        List<Variance> variances = new List<Variance>();

        PropertyInfo[] proppertyInfo = val1.GetType().GetProperties();
        foreach (PropertyInfo p in proppertyInfo)
        {
            Variance v = new Variance();
            v.Prop = p.Name;
            v.valA = p.GetValue(val1);
            v.valB = p.GetValue(val2);

            switch (v.valA)
            {
                case null when v.valB == null:
                    continue;
                case null:
                    variances.Add(v);
                    continue;
            }

            if (v.valA.Equals(v.valB)) continue;


            if (typeof(IEnumerable).IsAssignableFrom(p.PropertyType))
            {
                //string
                if (p.PropertyType == typeof(string))
                {
                    variances.Add(v);
                    continue;

                }


                var args = p.PropertyType.GetGenericArguments();
                MethodInfo exceptMethods = null;

                if (args.Length == 2) //dictionaries
                {
                    //variances.Add(v); // add to difference while not able to compare

                    var typeKeyValuePair = typeof(KeyValuePair<,>);
                    Type[] typeArgs = { args[0], args[1] };

                    exceptMethods = typeof(Enumerable)
                        .GetMethods(BindingFlags.Static | BindingFlags.Public)
                        .FirstOrDefault(mi => mi.Name == "Except")
                        ?.MakeGenericMethod(typeKeyValuePair.MakeGenericType(typeArgs));
                }

                else if (args.Length == 1)//lists
                {
                    exceptMethods = typeof(Enumerable)
                        .GetMethods(BindingFlags.Static | BindingFlags.Public)
                        .FirstOrDefault(mi => mi.Name == "Except")
                        ?.MakeGenericMethod(p.PropertyType.GetGenericArguments().FirstOrDefault());
                }

                else//not 
                {
                    variances.Add(v);
                }




                if (exceptMethods != null)
                {
                    try
                    {
                        var res1 = (IEnumerable)exceptMethods.Invoke(v.valA, new[] { v.valA, v.valB });
                        var res2 = (IEnumerable)exceptMethods.Invoke(v.valB, new[] { v.valB, v.valA });
                        // TODO: maybe implement better comparisson 
                        if (res1.OfType<object>().Any() != res2.OfType<object>().Any()) variances.Add(v);

                    }
                    catch (Exception ex)
                    {

                    }


                    /* if (v.valA.Except(v.valB).Any() || v.valB.Except(v.valA).Any())
                    {
                        variances.Add(v);
                    }*/


                }


            }

        }
        return variances;
    }

    public class Variance
    {
        public string Prop { get; set; }
        public object valA { get; set; }
        public object valB { get; set; }

        public override string ToString() => $" Property {Prop} is either {valA} resp. {valB}";
    }
void TestFunction()
{
var v1=new{yes=“asdf”,no=“as”,ar=new List(){1,2,3},dict=new Dictionary(){{1,1},{2,2}};
var v2=new{yes=“asdf”,no=“fd”,ar=new List(){1,2,3},dict=new Dictionary(){{1,1},{2,2}}};
var差异=详细比较(v1、v2);
}
公共静态列表DetailedCompare(T val1,T val2)
{
列表差异=新列表();
PropertyInfo[]proppertyInfo=val1.GetType().GetProperties();
foreach(PropertyInfo中的PropertyInfo p)
{
方差v=新方差();
v、 Prop=p.名称;
v、 valA=p.GetValue(val1);
v、 valB=p.GetValue(val2);
开关(v.valA)
{
当v.valB==null时为空:
继续;
大小写为空:
差异。添加(v);
继续;
}
如果(v.valA等于(v.valB))继续;
if(typeof(IEnumerable).IsAssignableFrom(p.PropertyType))
{
//串
if(p.PropertyType==typeof(string))
{
差异。添加(v);
继续;
}
var args=p.PropertyType.GetGenericArguments();
MethodInfo exceptMethods=null;
if(args.Length==2)//字典
{
//差异。添加(v);//添加到差异中,但无法进行比较
var typeKeyValuePair=类型(KeyValuePair);