【问题标题】:Expression.MemberInit -- The best overloaded method match has some invalid argumentsExpression.MemberInit -- 最佳重载方法匹配有一些无效参数
【发布时间】:2014-07-25 15:41:01
【问题描述】:

我有一个与以下代码相关的问题;基本上我想创建一个动态 LINQ 表达式,它允许我在 LINQ 中基于字符串创建一个 Select 语句:

public class SelectBuilder<T, T>
{
    Func<T, T> CreateNewStatement(string fields)
    {
        // input parameter "o"
        var xParameter = Expression.Parameter(typeof(T), "o");

        // new statement "new Data()"
        var xNew = Expression.New(typeof(T));

        // create initializers
        var bindings = fields.Split(',').Select(o => o.Trim())
            .Select(o =>
            {

                // property "Field1"
                var mi = typeof(T).GetProperty(o);

                // original value "o.Field1"
                var xOriginal = Expression.Property(xParameter, mi);

                // set value "Field1 = o.Field1"
                return Expression.Bind(mi, xOriginal);
            }
        );

        // initialization "new Data { Field1 = o.Field1, Field2 = o.Field2 }"
        var xInit = Expression.MemberInit(xNew, bindings); // <-- Error on this line

        // expression "o => new Data { Field1 = o.Field1, Field2 = o.Field2 }"
        var lambda = Expression.Lambda<Func<T, T>>(xInit, xParameter);

        // compile to Func<Data, Data>
        return lambda.Compile();
    }
}

这是 LINQ 表达式:

var vLINQ = (from a in PrimaryTable.AsEnumerable()
                                 join b in vDTsec.AsEnumerable()
                                 on a.Field<Object>("ID") equals b.Field<Object>("ID")
                                 into Group
                                 from q in Group.DefaultIfEmpty()
                                 select q).Select(MYSELECTSTRING);

这是错误:

编译器在 Microsoft FW 3.5 中出现问题;使用 FW 4.0 或更高版本我没有问题。但我需要在 3.5 中编译项目。 有人知道这个问题的解决方法吗?

【问题讨论】:

    标签: c# .net linq


    【解决方案1】:

    您遇到了方差问题。您的bindings 变量是IEnumerable&lt;MemberAssignment&gt;,其中MemberInit 期待IEnumerable&lt;MemberBinding&gt;。由于 T 在 .NET 4.0 中的 IEnumerable&lt;out T&gt; 是协变的,因此它可以正常工作。为了进一步说明这个问题,正在发生的事情是这样的:

    IEnumerable<MemberBinding> foo = bindings;
    

    您可以通过像这样转换绑定来轻松解决此问题:

    var bindings = fields.Split(',').Select(o => o.Trim())
                .Select(o =>
                {
    
                    // property "Field1"
                    var mi = typeof(TA).GetProperty(o);
    
                    // original value "o.Field1"
                    var xOriginal = Expression.Property(xParameter, mi);
    
                    // set value "Field1 = o.Field1"
                    return (MemberBinding)Expression.Bind(mi, xOriginal);
                }
            );
    

    这将始终有效,因为 MemberAssignment 派生自 MemberBinding。

    【讨论】:

    • 你去!...太好了!,非常感谢。工作愉快。
    • 我们也可以通过指定类型参数来强制LINQ方法的返回类型,即Select&lt;string, MemberBinding&gt;
    猜你喜欢
    • 2015-10-14
    • 2018-07-14
    • 2013-01-07
    • 2014-05-17
    • 2014-04-14
    • 2012-12-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多