c# - Expression.MemberInit -- 最佳重载方法匹配有一些无效参数

标签 c# .net linq

我有一个与以下代码相关的问题;基本上我想创建一个动态 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);

这是错误: Error

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

最佳答案

您遇到了方差问题。您的bindings变量是 IEnumerable<MemberAssignment>哪里MemberInit期待IEnumerable<MemberBinding> 。自 T协变于 IEnumerable<out T>在.NET 4.0中,它工作得很好。为了进一步说明这个问题,发生的事情是这样的:

IEnumerable<MemberBinding> foo = bindings;

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

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。

关于c# - Expression.MemberInit -- 最佳重载方法匹配有一些无效参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24959506/

相关文章:

c# - 使用 WEB API 的 EntityFramework,更新所有属性

javascript - 单击时使用 jquery 从数据网格行获取值

c# - 通过 lambda 表达式传递属性名称以读取属性值

c# - 如何将Microsoft的Dynamic Linq的OrderBy存储在变量中?

c# - 如何创建 Nullable<T> 的实例?

c# - 哪个更好 lambda 表达式或

c# - 标记界面的目的是什么?

c# - EF6 DbSet<T> 在 Moq 中返回 null

c# - WPF Datepicker - SelectedDate 只是日期而不是时间

javascript - Pusher 是否允许非 ASCII (JSON) 格式的传输负载?