无法从用法中推断出如何解决错误.尝试显式指定类型参数? [英] How to solve the error cannot be inferred from the usage. Try specifying the type arguments explicitly?

查看:148
本文介绍了无法从用法中推断出如何解决错误.尝试显式指定类型参数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

static Func<T, object> CreateSelector<T>(IEnumerable<string> propertyNames)
{
    var sourceType = typeof(T);
    var parameter = Expression.Parameter(sourceType, "e");
    var properties = propertyNames.Select(name => Expression.PropertyOrField(parameter, name)).ToArray();
    var selector = Expression.Lambda<Func<T, object>>(
        Expression.Call(typeof(Tuple), "Create", properties.Select(p => p.Type).ToArray(), properties),
        parameter);
    return selector.Compile();
}
public static IEnumerable<Tuple<T, T>> Join<T>(this IEnumerable<T> left, IEnumerable<T> right, IEnumerable<string> propertyNames)
{
    var keySelector = CreateSelector<T>(propertyNames);
    return left.Join(right, keySelector, keySelector, Tuple.Create);
}
public static bool CompareLists<T1, T2>(IEnumerable<T1> lstProduct1, IEnumerable<T2> lstProduct2, List<DuplicateExpression> DuplicateExpression)
{
    string[] Fields = DuplicateExpression.Select(x => x.ExpressionName).ToArray();
    var JoinExp = lstProduct1.Join(lstProduct2, Fields);
    bool IsSuccess = true;// CompareTwoLists(lstProduct1, lstProduct2, (listProductx1, listProductx2) => JoinExp.Any());

    return IsSuccess;
}

当我编译上面的代码时;我在第

行下出现错误

var JoinExp = lstProduct1.Join(lstProduct2, Fields);

错误是

错误1方法的类型参数 'AP.Classes.ListComparison.Join(System.Collections.Generic.IEnumerable, System.Collections.Generic.IEnumerable, System.Collections.Generic.IEnumerable)'无法推断 从用法.尝试指定类型参数 明确地. D:\ Workshop \ Ap \ Classes \ DuplicateValidator.cs

如何解决此错误?我正在创建一个列表比较工具.

解决方案

提供的自定义Join方法不适用,因为它期望一个泛型类型参数,而方法有两个.

您可以使用提供的CreateSelector实现来实现自定义Join/GroupJoin扩展方法,类似于Enumerable类中相应的系统提供的方法,如下所示:

public static IEnumerable<TResult> Join<TOuter, TInner, TResult>(this IEnumerable<TOuter> outer, IEnumerable<TInner> inner, IEnumerable<string> propertyNames, Func<TOuter, TInner, TResult> resultSelector)
{
    return outer.Join(inner, CreateSelector<TOuter>(propertyNames), CreateSelector<TInner>(propertyNames), resultSelector);
}

public static IEnumerable<TResult> GroupJoin<TOuter, TInner, TResult>(this IEnumerable<TOuter> outer, IEnumerable<TInner> inner, IEnumerable<string> propertyNames, Func<TOuter, IEnumerable<TInner>, TResult> resultSelector)
{
    return outer.GroupJoin(inner, CreateSelector<TOuter>(propertyNames), CreateSelector<TInner>(propertyNames), resultSelector);
}

然后,您可以使用上面的自定义GroupJoin有效地实现您的方法:

public static bool CompareLists<T1, T2>(IEnumerable<T1> list1, IEnumerable<T2> list2, List<DuplicateExpression> DuplicateExpression)
{
    var fields = DuplicateExpression.Select(x => x.ExpressionName).ToArray();
    return list1.GroupJoin(list2, fields, (x, match) => match).All(match => match.Any())
        && list2.GroupJoin(list1, fields, (x, match) => match).All(match => match.Any());
}

static Func<T, object> CreateSelector<T>(IEnumerable<string> propertyNames)
{
    var sourceType = typeof(T);
    var parameter = Expression.Parameter(sourceType, "e");
    var properties = propertyNames.Select(name => Expression.PropertyOrField(parameter, name)).ToArray();
    var selector = Expression.Lambda<Func<T, object>>(
        Expression.Call(typeof(Tuple), "Create", properties.Select(p => p.Type).ToArray(), properties),
        parameter);
    return selector.Compile();
}
public static IEnumerable<Tuple<T, T>> Join<T>(this IEnumerable<T> left, IEnumerable<T> right, IEnumerable<string> propertyNames)
{
    var keySelector = CreateSelector<T>(propertyNames);
    return left.Join(right, keySelector, keySelector, Tuple.Create);
}
public static bool CompareLists<T1, T2>(IEnumerable<T1> lstProduct1, IEnumerable<T2> lstProduct2, List<DuplicateExpression> DuplicateExpression)
{
    string[] Fields = DuplicateExpression.Select(x => x.ExpressionName).ToArray();
    var JoinExp = lstProduct1.Join(lstProduct2, Fields);
    bool IsSuccess = true;// CompareTwoLists(lstProduct1, lstProduct2, (listProductx1, listProductx2) => JoinExp.Any());

    return IsSuccess;
}

When I compile the above code; I am getting error on below line

var JoinExp = lstProduct1.Join(lstProduct2, Fields);

Error is

Error 1 The type arguments for method 'AP.Classes.ListComparison.Join(System.Collections.Generic.IEnumerable, System.Collections.Generic.IEnumerable, System.Collections.Generic.IEnumerable)' cannot be inferred from the usage. Try specifying the type arguments explicitly. D:\Workshop\Ap\Classes\DuplicateValidator.cs

How to solve this error? I am creating a List comparison tool.

解决方案

The provided custom Join method is not applicable, because it expects one generic type argument while your method has two.

You can use the provided CreateSelector implementation to implement custom Join / GroupJoin extension methods similar to the corresponding system provided methods in Enumerable class like this:

public static IEnumerable<TResult> Join<TOuter, TInner, TResult>(this IEnumerable<TOuter> outer, IEnumerable<TInner> inner, IEnumerable<string> propertyNames, Func<TOuter, TInner, TResult> resultSelector)
{
    return outer.Join(inner, CreateSelector<TOuter>(propertyNames), CreateSelector<TInner>(propertyNames), resultSelector);
}

public static IEnumerable<TResult> GroupJoin<TOuter, TInner, TResult>(this IEnumerable<TOuter> outer, IEnumerable<TInner> inner, IEnumerable<string> propertyNames, Func<TOuter, IEnumerable<TInner>, TResult> resultSelector)
{
    return outer.GroupJoin(inner, CreateSelector<TOuter>(propertyNames), CreateSelector<TInner>(propertyNames), resultSelector);
}

Then you can use the above custom GroupJoin to efficiently implement your method:

public static bool CompareLists<T1, T2>(IEnumerable<T1> list1, IEnumerable<T2> list2, List<DuplicateExpression> DuplicateExpression)
{
    var fields = DuplicateExpression.Select(x => x.ExpressionName).ToArray();
    return list1.GroupJoin(list2, fields, (x, match) => match).All(match => match.Any())
        && list2.GroupJoin(list1, fields, (x, match) => match).All(match => match.Any());
}

这篇关于无法从用法中推断出如何解决错误.尝试显式指定类型参数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆