1
votes

I'm looking for a following pattern:

I have several methods like this:
1. private bool CheckIfStringExist(string lookupString, ref string errorMessage)
2. private bool NumbersAreEqual(int one, int two, ref string errorMessage)
...
(around 15 of those).

What I want to do is to run them in a specific order and output error message to a user if any of those failed. Also I want to display method friendly names to a user.

So far, I came up with the following.

i create a class to hold each method separately:

public class CheckingMethod
{
    public string name {get; set;}
    public Action method {get; set;}
    public bool success {get; set;}

    public CheckingMethod(string name, Action method)
    {
        this.name= name;
        this.method = method;
        this.success = false;
    }
}

This allows me to store all of the methods in a list...like this:

List<CheckingMethod> cms = new List<CheckingMethod>();
cms.Add(new CheckingMethod("Check if text exist", ()=>CheckIfStringExist(lookupString, ref errorMessage);
cms.Add(new CheckingMethod ("Check if numbers are equal", ()=>NumbersAreEqual(num1, num2, ref errorMessage);

Then I can run them one by one like this:

foreach (CheckingMethod cm in cms)
{
    cm.method()
}

Unfortunately Action returns only void type, so I have no way of telling whether my method returned false or true. Also, I need to prohibit running of the next method if previous returned false (not always though, just in some cases).

4

4 Answers

3
votes

Action is just a delegate, and it is designed to be used without a return type

But you can change the Action delegate for a Func delegate

public Func<bool> method {get; set;}

Also, I need to prohibit running of the next method if previous returned false (not always though, just in some cases).

One way to solve this is:

  1. Add a property to your class to identify if the next method should be run if the return type is not true

    public bool RunNextMethodIfConditionFails {get; set;}
    
  2. Check this property on your foreach loop:

    foreach (CheckingMethod cm in cms)
    {
        var res = cm.method();
        if (!res && !cm.RunNextMethodIfConditionFails)
        {
            // react to this case, throw an exception or exit the loop using break
        }
    }
    
2
votes

Use Func<bool> rather than Action. Func is for delegates that return a value.

1
votes

Use the delegate Func<T, TResult> that accept a return type.

0
votes

Use Func instead

Public class CheckingMethod { public string name {get; set;} public Func method {get; set;} public bool success { get { return method(); }}

  public CheckingMethod(string name, Func<Bool> method) 
   { 
    this.name= name; 
    this.method = method; 
   } 
} 

List<CheckingMethod> cms = new List<CheckingMethod>();  
cms.Add(new CheckingMethod("Check if text exist", ()=>CheckIfStringExist(lookupString, ref errorMessage);  
cms.Add(new CheckingMethod ("Check if numbers are equal", ()=>NumbersAreEqual(num1, num2, ref errorMessage);

bool AllOK=true;
foreach (var cm in cms) {
  if (!cm.success) {
    AllOK=false;
    Debug.WriteLine("Failed on :" + cm.name);
    break; // this stops the for loop
  }
}

AllOk Will be false if failed.