接受Expression <func <t>&gt;的扩展方法表达式作为参数

时间:2015-10-14 09:05:18

标签: c# lambda expression .net-4.5 extension-methods

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

我可以做反射没有问题所以考虑更多的训练练习而不是我试图解决实际问题。

目前,扩展方法位于static类中,如下所示:

    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)

然而它给了我编译错误:

  

错误1委托'System.Func'不带1   参数C:\ hg \ Website \ Areas \ Wills \ ViewModel \ Answers.cs 38 59网站   enter image description here

这让我皱眉,因为我不认为我传递任何论据(是吗?)。可以取悦比我自己更聪明的人解释我的哪些期望是错误的。

万一我不清楚,我会重申。 我想要的是能够打电话     如果var emptyIfNewObject = answer.GetNullIfNotSet(o => o.HasBusinessAssets) nullId,则answer并获取0

3 个答案:

答案 0 :(得分:14)

根本不需要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);
}

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

更新(根据您的要求):

为了能够为所有传递的属性返回null,方法签名已更改为返回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)

哪个不太理想。

答案 1 :(得分:7)

您似乎需要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);
     } 

答案 2 :(得分:0)

是的,你可以:

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

}

你可以使用:

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