I've been doing C# now for about two months. And I want to create a method that does the following:
- Takes a string.
- Takes an array with conditions that needs to be applied to the string.
- Modifies the string within the called method.
- Checks if the modified string fulfills all boolean conditions.
- 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);