问题
Hi guys i have a question which is : how to directly execute a function or delegate as well as returning a value from a method using one single Expressional return statement in C#
*For reference, I am using C#7
In this context I need to return to the user an Object which has been generated like this:
object obj = cmd.ExecuteScalar();
I also have a logging function which I want to call:
DoLog(cmd.CommandText)
PS: I am 100% aware that I can achieve this non-conditionally using a couple of if statements in a much easier way - i'm simply asking if anyone can provide me with the most elegant "one liner" approach possible.
Here is a standard example of how conditional return expressions usually work
return (someBool)
? value1
: value2;
this will return 'value1' if someBool is TRUE;
Basically my question is can i do something like this
return (chkStatus)
? (obj & DoLog(cmd.CommandText))
: null;
In response to some of you who have suggested that I can use a single pipe operator to split the return, while your suggestions are in good faith, I assume you never tried to compile them
If you had you would see that it doesn't work as the types: Object and Void are NOT directly comparable thus causing a compile time error.
My request for a more refined / elegant method still stands.
回答1:
You can work something out using lambda's, but it will not be a clean syntax:
return (chkStatus
? (Func<object>)(() => {
DoLog(cmd.CommandText);
return obj;
})
: () => null)();
回答2:
I assume you want to return obj
, but also execute DoLog
which i'll assume has no return value.
If you're dead set on wanting to extract this logic, you could write yourself an extension method:
public static T AndExecute<T>(this T returnValue, Action action)
{
action();
return returnValue;
}
return (chkStatus) ? obj.AndExecute(() => DoLog(cmd.CommandText)) : null;
Although for sake of readability i would leave it as is - it clearly conveys its purpose.
回答3:
My solution has been derived from
Credit is due to these guys:
* Gvs
* xdecdec
His idea to use a base-inline lambda expression to do this dynamically but I have refined it into a much neater, much more understandable format (based on xdecdec's solution) - for those of you who are new or unknown to lambda / the newer syntax available;
public object ExecScalar(OdbcCommand cmd, bool async = true) {
try {
Enable(async);
// Create new scalar object
object obj = cmd.ExecuteScalar();
// Run log and fetch obj if !null
return obj?.AndExecute(() => DoLog(cmd.CommandText));
}
catch {
throw;
}
finally {
Disable();
}
}
I have based this off of user: GvS's rudimentary implementation of lambda
you could even modify this to accept an Array/List of Actions... SO upon return, you can tell you app to do 5 things and then return the value.. in one line..
I will leave that up to you to decide if that is something you are prepared to try, it is certainly not conventional, that's for sure
Anyway, so if anyone is ever looking to do this you will need :
public static class classExtention{
public static T AndExecute<T>(this T returnValue, Action action) {
if (returnValue != null) {
action();
}
return returnValue;
}
}
and then you can call this within your instance member.
A 1 line, conditional statement that executes an optional void.
来源:https://stackoverflow.com/questions/57906370/c-sharp-expressional-if-statements-possible-expansion