接受 Expression<Func<T>> 表达式作为参数的扩展方法

Extension method that accepts Expression<Func<T>> expression as parameter

我正在使用 .NET4.5C# 我想创建扩展方法,允许我传递对象的 属性,如果该对象的 ID 为 0,则 return null 否则 return 即 属性 值。

我可以通过反思来解决问题,所以考虑更多的是训练练习,而不是我试图解决实际问题。

当前扩展方法位于 static class 中,如下所示:

    public static object GetNullIfNotSet(this WillAnswer answer, Expression<Func<WillAnswer>> expression)
    {
        if (answer.Id == 0) return null;
        return expression.Compile()();
    }

我希望能够使用它的方式如下(答案类型为 WillAnswer):

var emptyIfNewObject = answer.GetNullIfNotSet(o => o.HasBusinessAssets)

但是它给我编译错误:

Error 1 Delegate 'System.Func' does not take 1 arguments C:\hg\Website\Areas\Wills\ViewModel\Answers.cs 38 59 Website

这让我皱眉,因为我认为我没有传递任何论点(是吗?)。请比我聪明的人解释一下我的哪些期望是错误的。

以防万一我不清楚我会重申。 我想要的是可以打电话 var emptyIfNewObject = answer.GetNullIfNotSet(o => o.HasBusinessAssets) 并得到 null 如果 answerId0.

根本不需要Expression,只需使用Func<WillAnswer, TProp>:

public static TProp GetNullIfNotSet<TProp>(this WillAnswer answer, Func<WillAnswer, TProp> func)
{
    if (answer.Id == 0) return default(TProp);
    return func(answer);
}

请注意,这并不总是 return null 而是默认值(如果 属性 是值类型)。

更新(根据您的要求):

为了能够return null所有传递的属性,方法签名改为return object

public static object GetNullIfNotSet<TProp>(this WillAnswer answer, Func<WillAnswer, TProp> func)
{
    if (answer.Id == 0) return null;
    return func(answer);
}

但是,您将失去泛型的好处,并且最终会显式转换为 Nullable<T>:

var emptyIfNewObject = (bool?)answer.GetNullIfNotSet(o => o.HasBusinessAssets)

不太理想。

您似乎需要 Func<WillAnswer, T> 而不是 表达式:

  public static T GetDefaultIfNotSet<T>(this WillAnswer answer, Func<WillAnswer, T> func) {
    if (null == answer)   
      throw new ArgumentNullException("answer");
    else if (null == func)   
      throw new ArgumentNullException("func");

    return answer.Id == 0 ? return default(T) : func(answer);
  }

编辑:如果你想确保 null你可以限制泛型T:

     public static T GetNullIfNotSet<T>(this WillAnswer answer, Func<WillAnswer, T> func) 
       where T: class { // no structs here
         if (null == answer)   
           throw new ArgumentNullException("answer");
         else if (null == func)   
           throw new ArgumentNullException("func");

         return answer.Id == 0 ? return null : func(answer);
     } 

是的,你可以:

public static void LoadProperty<T>(this T t, Func<T, object> func) where T: Entity
{       

}

你可以使用:

contact.LoadProperty(p => p.LogicalName);