Reputation: 3264
Say I have some code like this
var addResult = GetAddResult(num1, num2);
var transformedResult = TransformResult(addResult );
if(CheckValidity(transformedResult))
{
SendResult(transformedResult);
}
else
{
LogError(transformedResult);
}
I am writing such code in many places. Basically it is a function calls where the return value of one is the input of another. Also there are flow changes depends on some conditional checks.
Is there a way to write this in a more readable way?
For example
ExecuteFlow.GetAddResult(num1,num2).TransformResult.CheckValidity.IfTrue.SendResult.IfFalse.LogError
;
Apologies for this is more of a conceptual clarification. But I would like to know if such a technique is feasible.
Upvotes: 0
Views: 2448
Reputation: 2742
Result.OfAdding(1, 2)
.Transform()
.IfValid(thenInvokeThis: () => Debug.Print("Valid"),
elseInvokeThis: () => Debug.Print("Invalid"));
A bit of a twist on Dabbas's solution - the IsValid works really nicely, but I felt the initial setup could be smoother.
Firstly declaring a common interface and a static factory.
interface IAddResult
{
int AddendA { get; set; }
int AddendB { get; set; }
int Sum { get; }
}
static class Result
{
public static IAddResult OfAdding(int a, int b)
{
// TODO: Return add result.
throw new NotImplementedException();
}
}
And then adding chaining functionality via extensions.
static class AddResultExtensions
{
public static IAddResult Transform(this IAddResult addResult)
{
// TODO: Transform add result.
throw new NotImplementedException();
}
public static void IfValid(this IAddResult addResult, Action thenInvokeThis,
Action elseInvokeThis)
{
// TODO: Validate.
bool isValid = true ? throw new NotImplementedException()
: false;
if (isValid)
{
thenInvokeThis();
}
else
{
elseInvokeThis();
}
}
}
Upvotes: 0
Reputation: 3230
I think you can do this
//let's assume this is the type that GetAddResult method is returning.
public class MyAddResult { ... }
//let's say this is what method TransformResult is returning.
public class MyTransformResult { ... }
public static class MyFlow {
public static MyTransformResult TransformResult(this MyAddResult src) {
....
}
public static void IfValid(this MyTransformResult src, Action<MyTransformResult> methodIfTrue, Action<MyTransformResult> methodIfFalse) {
if( CheckValidity(src) )
methodIfTrue(src);
methodIfFalse(src);
}
}
//In another place
public void SendResult(MyTransformResult m) { ... }
//In another place
public void LogError(MyTransformResult m) { ... }
The usage will be:
GetAddResult(num1, num2).TransformResult().IfValid(SendResult, LogError);
Upvotes: 2
Reputation: 36710
You could write a C# extensions,
e.g.
GetAddResult(num1, num2).Handle();
where the extension would be:
public static void Handle(this AddResult addResult)
{
var transformedResult = TransformResult(addResult);
if(CheckValidity(transformedResult))
{
SendResult(transformedResult);
}
else
{
LogError(transformedResult);
}
}
OR a bit more verbose:
GetAddResult(num1, num2).ToTransformResult().HandleValidity();
with these extensions:
public static TransformResult ToTransformResult(this AddResult addResult)
{
return TransformResult(addResult);
}
public static void HandleValidity(this TransformResult addResult)
{
if(CheckValidity(transformedResult))
{
SendResult(transformedResult);
}
else
{
LogError(transformedResult);
}
}
Not sure if that would fullfil all your requirements.
Upvotes: 1