为什么有些对象属性是UnaryExpression和其他的MemberExpression?

Pro*_*ofK 70 .net linq linq-expressions

根据我使用lambda而不是字符串属性名称问题选择模型属性的答案,想要向集合添加属性,如下所示:

var props = new ExportPropertyInfoCollection<JobCard>();
props.Include(model => model.BusinessInstallNumber).Title("Install No").Width(64).KeepZeroPadding(true);
props.Include(model => model.DeviceName).Title("Device").Width(70);
props.Include(model => model.DateRequested).Title("Request Date").Format("{0:dd/MM/yyyy}").Width(83);
Run Code Online (Sandbox Code Playgroud)

我在Include方法中编写了以下代码:

public class PropertyCollection<T>
{
    public void Include(Expression<Func<T, object>> expression)
    {
        var memberExpression = expression.Body as MemberExpression;
        if (memberExpression != null)
        {
            var pes = new ExportPropertyInfoBuilder {Property = new ExportPropertyInfo {Property = memberExpression.Member as PropertyInfo}};
            Properties.Add(pes.Property.Property.Name, pes.Property);
            return pes;
    }
Run Code Online (Sandbox Code Playgroud)

但是,在运行代码时,我发现一些lambda会按预期产生MemberExpression值,但是其他一些产生了UnaryExpression值.在使用lambdas添加所有属性之前,我必须将第一行代码更改为以下代码:

var memberExpression = expression.Body as MemberExpression ?? ((UnaryExpression) expression.Body).Operand as MemberExpression;
Run Code Online (Sandbox Code Playgroud)

所有属性都是"简单"类型,即POCO业务对象中的字符串,DateTime,int,bool等.它们使用多个不同的DataAnnotations属性进行修饰.

是什么导致我的示例中的一些lambdas产生MemberExpression值和其他UnaryExpression值?在我的示例中,第一个UnaryExpression位于第三行,即DateTime属性,但布尔属性也会导致UnaryExpressions.

lep*_*pie 58

我想我知道问题是什么.表达式返回类型object.

如果你改变这个Expression<Func<T, R>>应该正确推断返回类型,并且UnaryExpression(我将假设是一些装箱操作)不应该发生.

更新:

签名Include应该是:

public void Include<T, R>(Expression<Func<T, R>> expression)
Run Code Online (Sandbox Code Playgroud)

  • @ProfK:R只是推断,它将是返回的属性的类型.你可能不会使用它,但你可能:) (3认同)
  • @leppie T泛型类型参数已在类级别定义,因此如果意图不同或冗余,则应使用不同的类型参数名称 (3认同)
  • 我想我明白发生了什么。因为表达式返回类型是对象,所以是装箱的。使用类型化返回类型,这不会发生。谢谢@leppie!相信有能力的人会在这里提供帮助:-) (2认同)