Home > Software engineering >  How to parse a string and a bool array to a method, modifying the string in the method and verifying
How to parse a string and a bool array to a method, modifying the string in the method and verifying

Time:03-14

I've been doing C# now for about two months. And I want to create a method that does the following:

  1. Takes a string.
  2. Takes an array with conditions that needs to be applied to the string.
  3. Modifies the string within the called method.
  4. Checks if the modified string fulfills all boolean conditions.
  5. Then "returns"(using the ref) string to the caller method.

So for example, if I wanted the user to input their first and last name. I'd do:

GetStringLine(out string name, new bool[] { name.Length > 1, name.Split(' ').Length > 1})

I've been trying several different ways at this point, I believe I am simply missing something. It feels like there should be some way to tell the method that the bool condition being passed into the method should be applied to the actively modified string.

Anyways, as I don't have a whole lot of experience with C#, or programming, I am hoping that the following code block will explain or hint further to what I am trying to achieve. Really hoping to get some more understanding of this. So keep in mind, I don't need to do it exactly as I am showing, if there would be a another way of accomplishing my goals, I'd be happy to do that instead.

Best regards!

static void Main(string[] args) {
    string str = "test";
    GetStringLine(ref str, 
        new bool[] { 
            str.Length > 1, 
            str.Length < 3
        }
    );
}
public static void GetStringLine(ref string str, bool[] conditions) {
    while (!conditions.All(condition => condition)) {
        str = Console.ReadLine();
        Console.WriteLine("");
    }
}

Edit: After @pm100 's solution, I applied it as such and it works as expected:

public static void GetStringLine(out string output, Predicate<string>[] conditions) {
    string input = ""; 
    while (!conditions.All(condition => condition(input))) { 
        input = Console.ReadLine(); 
        Console.WriteLine(""); 
    } 
    output = input; 
} 

Although, I feel like it's a bit abundant due to the string input = "" and output = input. My first attempt was to do it like this:

public static void GetStringLine(out string output, Predicate<string>[] conditions) { 
    while (!conditions.All(condition => condition(output))) { 
        output = Console.ReadLine(); 
        Console.WriteLine(""); 
    }
}

Sadly, this yields me naught but two errors: First:

CS1628 Cannot use ref, out, or in parameter 'output' inside an anonymous method, 
lambda expression, query expression, or local function

Second:

CS0177  The out parameter 'output' must be assigned to before control 
leaves the current method

I'll add that my actual code contains more fluff, I.e. error prompts and other things that are needed, but I deemed it not relevant to the current question at hand.

CodePudding user response:

I leave out the looping to reprompt and just show the check against arbitrary conditions (since thats the tricky bit)

static bool CheckString(string input, Predicate<string>[] conditions) {
    conditions.All(c => c(input))
}

now to use

   var conditions = new Predicate<string>[] {
        (s)=>s.Length > 3,
        (s)=>s.Contains("a")
    };

    CheckString("abcdef", conditions); // true
    CheckString("ab", conditions);     // false

the hard part for you will be to tell the user on each reprompt what the conditions are. You cannot (easily) get a string representation of the predicates, probably should pass in a prompt string

Like this

static string ReadCheckedString(string prompt, Predicate<string>[] conditions) {

    while (true) {
        Console.WriteLine(prompt);
        var input = Console.ReadLine();
        if (input == null || input.Length == 0)
            return null;
        if (conditions.All(c => c(input))) {
            return input;
        }

    }
}

and

    var conditions = new Predicate<string>[] {
        (s)=>s.Length > 3,
        (s)=>s.Contains("a")
    };
   var ans =  ReadCheckedString("longer than 3 chars and contains 'a'", conditions);
  •  Tags:  
  • c#
  • Related