FUNC<>有2个输出值

时间:2014-09-23 14:35:23

标签: c# lambda expression func

是否有可能创建一个具有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)

有没有办法达到我想要的目的?

2 个答案:

答案 0 :(得分:5)

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

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

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

答案 1 :(得分:4)

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

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;}
}   

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