UPDATED: I am trying to write a method to do somes work and before it actually does those works it needs to go through some validations. Those validation varies based on what work it's going to do.
After some thoughts, I still want to use the same patterns with some minor changes. Now, I want to make the following code works:
SomeClass:
public SomeResponse DoSomething<T>(params Func<T, bool>[] validations)
{
if(validations.All(v=>v(T))
{
some logic..
}
return SomeResponse;
}
Usage:
private Func<SomeRequest, bool> ValidateName = r =>
{return !string.IsNullOrWhiteSpace(r.Name);};
private Func<SomeRequest, bool> ValidatePhone = r =>
{return !string.IsNullOrWhiteSpace(r.Phone);};
var someResponse = SomeClass.DoSomething<SomeRequest>(ValidateName,ValidatePhone);
Again, the code currently doesn't work because it's giving me error on
if(validations.All(v=>v(T))
basically Type parameter is not valid here, and I couldn't find a way to pass in an actual SomeRequest
object to the Func.
How should I write the code to loop through all the results return by the list of functions and make sure they are returning true, as well as keeping the flexibility of the Type parameter?
Answer:
Found a way to do that, hope this can be helpful:
Simply modify the method definition to :
SomeClass:
public SomeResponse DoSomething<T>(T request, params Func<T, bool>[] validations)
{
if(validations.All(v=>v(request))
{
some logic..
}
return SomeResponse;
}
Then use it like:
var someResponse = SomeClass.DoSomething<SomeRequest>(someRequest, ValidateName,ValidatePhone);
Please let me know if there is any other solution.
You're almost there!
First note that Validations
is an array of Func<Request, bool>
- that is, each item in the array is a function which takes a Request
as a parameter and returns a bool
.
So in order to get the bool
out of the Func
, you need to apply it to a Request
object. In C#, applying a Func
to an argument looks just like calling a method. So your LINQ expression will look like this:
validations.All(f => f(request))
This will return true
if and only if all of the functions in validations
return true
(when applied to request
).
So your full if
block will look like this:
// I'm just guessing what the code to make a Request object will look like
Request request = resource.GetRequest();
if (!validations.All(f => f(request)))
{
throw new Exception("Not all of the validations checked out");
}
You haven't provided enough context for me to tell you where to get a Request
object from but I'm sure you can figure it out.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With