【问题标题】:Func<> with 2 output values具有 2 个输出值的 Func<>
【发布时间】:2014-09-23 14:35:23
【问题描述】:

是否有可能创建一个具有 2 个输出值的函数?

我需要一种从对象中获取 2 个属性的方法,最好是通过表达式,因为 易于使用。 将它与查询提供程序一起使用来选择多个字段。

protected Expression<Func<T, TProperty1, TProperty2>> Select2Properties { get; set; }

public MyClass(Expression<Func<T, TProperty1, TProperty2>> selector) {
   Select2Properties = selector;
}

// desired usage (pseudo)
x => (x.Property1, x.Property);

我知道这完全是垃圾,但任何其他解决方案(例如,需要 2 个表达式属性选择器或需要一个元组)都会导致有时无法读取构造函数调用,尤其是当我需要超过 2 个属性时:

x => x.Property1, x => x.Property2, x => x.Property3, x => x.Property4
// or 
x => Tuple.Create(x.Property1, x.Property2, x.Property3, x.Property4)

有没有办法实现我想要的?

【问题讨论】:

    标签: c# lambda expression func


    【解决方案1】:

    如果您不喜欢Tuple 的语法,可以使用匿名类型从选择器中选择两个属性:

    x => new { x.Property1, x.Property };
    

    如果这在上下文中不可行(通常是因为类型需要在定义范围之外使用),那么当您希望选择时,您应该简单地创建命名类型以从选择器中选择多个值。

    【讨论】:

      【解决方案2】:

      Func&lt;...&gt; 只有常规参数。但是,您可以创建自己的委托类型:

      delegate bool Foo(string s, out int i, out char c);
      

      显然可以以任何你想要的方式混合......但是:你不能将它与Expression 混合,至少不能通过 C# 编译器的表达式树生成器:

      表达式树可能不包含赋值运算符

      表达式树 lambda 可能不包含 out 或 ref 参数

      带有语句体的 lambda 表达式不能转换为表达式树

      另一种选择是采用具有可变属性的参数。例如:

      delegate bool Foo(SomeArgs args);
      class SomeArgs {
          public string Name {get;set;}
          public int Count {get;set;}
          public char Whatever {get;set;}
      }   
      

      现在实现可以简单地更改参数的属性

      【讨论】:

      • 表达式的使用表明此代码可能被查询提供者使用,这几乎肯定不是一个可行的选择。
      • @Servy 是的,它不适用于查询提供程序;根据我刚才的编辑,它不能很好地与Expression 配合使用。
      • @Servy 是的,该表达式将被推送到一个规范中,然后将其应用于 IQueryable 以找到一个条目,其中 2 个属性等于 2 个传递的参数。所以是的,我需要一个表达式。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-05
      • 2019-05-08
      • 2017-09-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多