Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Func<> with 2 output values

Is it somehow possible to create a function that has 2 output values?

I need a way to get 2 properties from an object, preferably by expression because of ease of use. using it along with a query provider to select multiple fields.

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

I know this is complete rubbish, but any other solution (e.g. requiring 2 expression property selectors or requiring a tuple) results in sometimes unreadable constructor calls, especially when I require more than 2 properties:

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

Is there a way to achieve what I want?

like image 982
xvdiff Avatar asked Apr 18 '26 22:04

xvdiff


2 Answers

To select out two properties from a selector you can use an anonymous type, if you don't like the syntax of a Tuple:

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

If that isn't feasible in context (generally because the type needs to be used outside of the scope of where it is defined) then you should simply be creating named types to select out of your selectors when you wish to select out multiple values.

like image 134
Servy Avatar answered Apr 20 '26 12:04

Servy


Func<...> only has regular parameters. You can, however, create your own delegate type:

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

Obviously mix any way you want... However: you cannot mix that with Expression, at least not via the C# compiler's expression tree generator:

An expression tree may not contain an assignment operator

An expression tree lambda may not contain an out or ref parameter

A lambda expression with a statement body cannot be converted to an expression tree

The other option is to take parameters that have mutable properties. For example:

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

Now implementations can simply change the properties of the parameter.

like image 43
Marc Gravell Avatar answered Apr 20 '26 12:04

Marc Gravell



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!