I've been C# programming for about a year now and I normally get into problems like this by overlooking a detail somewhere. I feel like I am doing this again but I can't seem to solve the problem. I have a string variable named 'input' I have declared it in an 'if' statement in my 'Main' class like so:
string input = Console.Readline();
As a separate 'if' statement, in the same 'Main' class, I have written this:
if (input != null || input != 0)
{
//I have code for this part, but it is irrelevant
}
else
{
//And this part, but it is also irrelevant
}
my problem is that MonoDevelop is highlighting both of the 'input' variables in the second 'if' statement and saying 'the name input does not exist in the current context'. I feel like I am overlooking something, any help would be appreciated.
My full code is this:
using System;
namespace ConsoleTest
{
class MainClass
{
public static string version = "0.0.1";
public static string precursor = "/:>";
public static void Main (string[] args)
{
Console.Write ("Console Test ");
Console.WriteLine (version);
Console.Write (precursor);
string start = Console.ReadLine ();
if (start == "start") {
while (true) {
Console.WriteLine ("Started");
Console.Write (precursor);
string input = Console.ReadLine ();
}
} else {
Environment.Exit (0);
}
if (input != null || input != 0) {
//Code
} else {
Console.WriteLine("Error: Input null");
}
}
}
}
Declare your input variable before your first if statement. Because it is declared inside it is only available inside your if statement (or in this case inside your loop)
input exists only in the scope of your while loop inside your first if statement.
Move it outside.
string input = new string();
if (start == "start") {
while (true)
{
Console.WriteLine ("Started");
Console.Write (precursor);
input = Console.ReadLine ();
}
}
More code is needed, however it may be because you are trying to compare a String to an int. Perhaps you were looking for
input.equals("0")?
Edit: Looking at your code, you initialized the variable in the if statement. You have to initialize it at the beginning of your function. Even if you just set it to null.
public static void Main (string[] args)
{
Console.Write ("Console Test ");
Console.WriteLine (version);
Console.Write (precursor);
string start = Console.ReadLine ();
string input = null;
if (start == "start") {
while (true) {
Console.WriteLine ("Started");
Console.Write (precursor);
input = Console.ReadLine ();
}
} else {
Environment.Exit (0);
}
if (input != null || !input.equals("0")) {
//Code
} else {
Console.WriteLine("Error: Input null");
}
}
Your string input is declared inside your loop. Therefor, it isn't known after this loop.
Declare it outside your loop (and initiate it to null or String.Empty) then fill it inside your loop
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I was making a tool named "Ferna".. And I was trying to make different commands on it, but the problem is that these "commands" have to be in order, like when I try to execute a command, I have to execute them in order.. But I want it like it doesn't have to be in order so if i write "cyan" it executes it, it doesn't have to wait for the 5th ReadLine()
Here's my code:
using System;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
if (Console.ReadLine() == "cmds")
{
Console.WriteLine(cmds);
}
else if (Console.ReadLine() == "calculator")
{
cal.ShowDialog();
}
else if (Console.ReadLine() == "cyan")
{
Console.ForegroundColor = ConsoleColor.Cyan;
}
else if (Console.ReadLine() == "black")
{
Console.ForegroundColor = ConsoleColor.Black;
}
else if (Console.ReadLine() == "clear")
{
Console.Clear();
}
}
}
}
Store the results of your Console.ReadLine statement in a variable. This way you don't have to keep calling Console.ReadLine.
var cmd = Console.ReadLine();
if (cmd == "cmds")
{
Console.WriteLine(cmds);
}
else if (cmd == "calculator")
{
...
The issue is essentially every time the if checks each condition its going to wait for more input
Update :
You will need to put it in a loop
string cmd = "";
while(cmd != "exit")
{
cmd = Console.ReadLine();
if (cmd == "cmds")
{
Console.WriteLine(cmds);
}
else if (cmd == "calculator")
{
...
}
Here is the good old switch statement. Gotta break it out every once in while! If/Else works just as well though. This will loop and check for the next line.
class Program
{
static void Main(string[] args)
{
while((string command = Console.ReadLine()) != null)
{
switch (command.ToUpper())
{
case "CMD":
Console.WriteLine("CMD");
break;
case "CALCULATOR":
cal.ShowDialog();
break;
default:
Console.WriteLine("Default");
break;
}
}
}
}
Using Queue<string> to keep a list of commands might not be a bad idea:
class Program
{
static Queue<string> commandQueue = new Queue<string>(new[] {"FirstCommand", "SecondCommand", "ThirdCommand"});
static void Main(string[] args)
{
using (Queue<string>.Enumerator enumerator = commandQueue.GetEnumerator())
{
while (enumerator.MoveNext())
{
Console.WriteLine("Type in next command or type exit to close application");
//this while is used to let user make as many mistakes as he/she wants.
while (true)
{
string command = Console.ReadLine();
if (command == "exit")
{
Environment.Exit(0);
}
//if typed command equals current command in queue ExecuteCommand and move queue to next one
if (command == enumerator.Current)
{
ExecuteCommand(command);
break;
}
else//Show error message
{
if (commandQueue.Contains(command))
{
Console.WriteLine("Wrong command.");
}
else
{
Console.WriteLine("Command not found.");
}
}
}
}
Console.WriteLine("We are done here, press enter to exit.");
Console.ReadLine();
}
}
//Method that executes command according to its name
static void ExecuteCommand(string commandName)
{
switch (commandName)
{
case "FirstCommand":
Console.WriteLine("FirstCommand executed");
break;
case "SecondCommand":
Console.WriteLine("SecondCommand executed");
break;
case "ThirdCommand":
Console.WriteLine("ThirdCommand executed");
break;
default:
Console.WriteLine("Command not found");
break;
}
}
}
Also if the requirement states that actions should performed in exact order it might not be a bad idea to just let the user press Enter to execute the next command instead of having to type its name.
So I want to make a list of names. I want this list to go on until user inputs 0 to quit, after user types 0 I want all names to be displayed. You probably see what I'm trying to do from the code below...that "typedName" is there just so you see what I'm trying to do.
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
List<string> names = new List<string>();
Console.WriteLine("Type in 0 to end.");
bool over = false;
while (over != true)
{
names.Add(Console.ReadLine());
if(typedName == "0")
{
over = true;
}
}
Console.WriteLine("Entered names : ");
names.ForEach(Console.WriteLine);
Console.ReadLine();
}
}
}
First you need the typedName to be captured and then check if it is equal to 0.
if it is not add it to the list
List<string> names = new List<string>();
Console.WriteLine("Type in 0 to end.");
while (true)
{
var typedName = Console.ReadLine();
if (typedName.Equals("0"))
{
break;
}
names.Add(typedName);
}
Console.WriteLine("Entered names : ");
foreach(var name in names)
{
Console.WriteLine(name);
}
Console.ReadLine();
if(typedName == "0")
Well, what is typedName? Or what should it be? I suspect it should be the input entered by the user, something like this:
var typedName = Console.ReadLine();
You can then add it to the list by using that variable:
names.Add(typedName);
And compare it with "0" as you already do, etc.
your code is not complete that is why is not working...
you are missing the most important part:
populate the list if and only if typedName != "0"
while (!over)
{
var typedName =Console.ReadLine();
if(typedName == "0")
{
over = true;
}else
{
Console.WriteLine("Enter a name... ");
names.Add(Console.ReadLine());
}
...
}
I am having a problem constructing a loop WHICH will COMPARE a VAR(userSelection) against the name ITEMS in my LIST(Listings). The goal is that if userSelection MATCHES name, getDescription will Console.WriteLine the GetDefinition and display the definition of the word in the list matched. Most of my code is working, and i've been working on this assignment for a week.
I'm very much a newb, please assume I know nothing. All help is appreciated. I think this would be a while loop, but i've played with all the loops now and am lost and confused. I'm a newb, please use small words and be as detailed as you can afford to be. It's greatly appreciated. Thank you.
My C# Program:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;// Needed for Streaming...
using System.IO;// Needed for Streaming...
namespace a090___StreamReader_DictionarySearch
{
class Program
{
private const String FILE_NAME = "dictionary.txt";//establish text file instance
public void Play()
{
do
{
DisplayTitle();
List<Listing> items = LoadListings();//create a list of WordDef objects
Console.Write(string.Join(" | ", items.Select(x => x.GetName()))); //Console.Write("\b \b");// Backspace would also of worked
DisplayText("\n\nPlease enter a word from the selections about to see it's definition");// Nice use of PROMPT
String userSelection = Console.ReadLine().ToLower();//Capture input
//loop through all of the listings, and compare each one to userSelection
//Then once it equals print definition
bool found = false;
foreach (Listing item in items)
{
if (userSelection == item.GetName())
{
Console.WriteLine("You selected: " + userSelection +
"\nWhich Means: " + item.GetDefinition());
found = true;
break;
}
}
if (!found)
{ Console.WriteLine("I'm sorry, I don't have a match for that."); }
} while (PlayAgain());
Salutation();
}
//ToolBox -- my program specific tools
public List<Listing> LoadListings()//load entries display as list
{
StreamReader fileIn = new StreamReader(FILE_NAME);
List<Listing> entry = new List<Listing>();
//loop through every line of the file
while (!fileIn.EndOfStream)
{
String line = fileIn.ReadLine();
String[] pieces = line.Split(':');
if (pieces.Length < 1) continue;//error handling - set to length of text items
Listing myListing = new Listing(pieces[0], pieces[1]);
entry.Add(myListing);
}
fileIn.Close(); return entry;
}
//MaxBox -- my useful tools
public void DisplayText(String StringNameIs)
{ Console.WriteLine(StringNameIs); }//Where are we?
public Boolean PlayAgain()
{
Console.Write("\n\nDo you select again? (y)es or (n)o: ");
String command = Console.ReadLine().ToLower();
if (command == "y" || command == "yes") return true;
return false;
}
public void Salutation()
{ Console.Clear(); Console.WriteLine("Ti Do - oh - oh Ti Do -- So Do!"); } //The last line from the 'do-re-mi' song from the Sound of Music
public void DisplayTitle()
{ Console.Clear(); Console.WriteLine(">>>-- A Dictionary of Sounds --<<< \n"); } //Announce Our Program
static void Main(string[] args)
{
Program DictionaryLookup = new Program();
DictionaryLookup.Play();
Console.Read();
}
}
}
My Class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace a090___StreamReader_DictionarySearch
{
class Listing
{
private String name;
private String definition;
public Listing(String name, String definition)
{ this.name = name;
this.definition = definition;}
public String GetName() {return name;}
public String GetDefinition() {return definition; }
}
}
My Text File
Doe: a deer, a female deer
Ray: a drop of golden sun
Me: a name I call myself
Far: a long, long way to run
Sew: a needle pulling thread
La: a note to follow Sew
Tea: a drink with jam and bread
This is untested, but should work, using your existing code.
Assuming each "name" (doe, ray, etc) only occurs once (which they do), then you can use Linq's "SingleOrDefault", which will return null if no match is found.
var selection = items.SingleOrDefault(x => x.GetName() == userSelection);
if (selection == null)
Console.WriteLine("I'm sorry, I don't have a match for that.");
else
Console.WriteLine("You selected: " + userSelection +
"\nWhich Means: " + selection.GetDefinition());
To ignore case during comparison, try modifying the above:
... items.SingleOrDefault(x => String.Compare(x.GetName(), userSelection, true));
There are a number of other things you could change here, but perhaps it won't matter for your assignment. For example, I'd eliminate the private variables in your Listing class and change the public "get" methods into properties:
public String Name { get; private set; }
public String Definition { get; private set; }
Substitute the code
while (true)
{
if (userSelection == name)
{Console.WriteLine("You selected: " + Listing.userSelection() +
"\nWhich Means: " + Listing.items.GetDefinition());}
}
else { Console.WriteLine("I'm sorry, I don't have a match for that."); }
with this
bool found = false;
foreach (Listing item in items)
{
if (userSelection == item.GetName().ToLower())
{
Console.WriteLine("You selected: " + userSelection +
"\nWhich Means: " + item.GetDefinition());
found = true;
break;
}
}
if (!found)
{ Console.WriteLine("I'm sorry, I don't have a match for that."); }
I have use the foreach statement; with this statement you can iterate all items of your collection.
Inside the foreach loop I check if the element Name is equal with the user input, if match I set a bool variable indicating element found.
After the loop if element not found print the message.
NB Obviously this code can be written more concisely with LINQ.
i am using command line arguments and if conditions are used to check the input values but it is not looking good can i change it to switch but i have no idea how to change it my code is
if (args.Length > 0 && args.Length == 4)
{
string programName = args[0];
string file1= args[2];
string file2= args[3];
bool flag = false;
int num= 0;
bool isNum = Int32.TryParse(args[1].ToString(), out num);
if (!(programName.Equals("Army")))
{
Console.WriteLine("Error");
}
if (!Int32.TryParse(args[1].ToString(), out isNum ))
{
Console.WriteLine("value should be a number");
}
if (!File.Exists(file1))
{
Console.WriteLine("file 1 does not exist");
}
if (!File.Exists(file2))
{
Console.WriteLine("file 2 does not exist");
}
A switch statement isn't really called for here. That's useful when you have a single value and need to select from a series of possible mutually-exclusive steps based on that value. But that's not what you're doing here. These aren't a chain of if/else if statements keying off a value, these are more like guard clauses. All of them need to run in order to determine all of the output to show to the user.
You can shorten the code by removing the curly braces:
if (!(programName.Equals("Army")))
Console.WriteLine("Error");
if (!Int32.TryParse(args[1].ToString(), out isNum ))
Console.WriteLine("value should be a number");
if (!File.Exists(file1))
Console.WriteLine("file 1 does not exist");
if (!File.Exists(file2))
Console.WriteLine("file 2 does not exist");
You could also extract these lines of code into their own method, which would make the Main method a little cleaner. You could even extract the conditional checks themselves into very small methods to make it more prose-like for readability. But the conditional structure itself doesn't really need to change.
You can create class which will be responsible for retrieving and checking your application arguments. E.g. if your application has name Zorg, you can create following class:
public class ZorgConfiguration
{
private string num;
private string programName;
private string file1;
private string file2;
public static ZorgConfiguration InitializeFrom(string[] args)
{
if (args.Length < 4)
throw new ZorgConfigurationException("At least 4 arguments required");
return new ZorgConfiguration {
ProgramName = args[0],
Num = args[1],
File1 = args[2],
File2 = args[3]
};
}
// to be continued
}
As you can see, it's responsibility is to hold application settings. It has static method for creating instance of configuration from args array. This method checks if arguments count correct and then initializes each property of configuration class with appropriate argument. Checking argument value moved to properties:
public string ProgramName
{
get { return programName; }
private set {
if (value == "Army")
throw new ZorgConfigurationException("Error");
programName = value;
}
}
public string Num
{
get { return num; }
private set {
int i;
if (!Int32.TryParse(value, out i))
throw new ZorgConfigurationException("value should be a number");
num = value;
}
}
public string File1
{
get { return file1; }
private set {
if (!File.Exists(value))
throw new ZorgConfigurationException("file 1 does not exist");
file1 = value;
}
}
Each property is responsible for verifying corresponding argument value. If value is incorrect, then custom ZorgConfigurationException (that is simply class inherited from Exception) is thrown.
Now main application code looks very clean:
try
{
var config = ZorgConfiguration.InitializeFrom(args);
// you can use config.File1 etc
}
catch (ZorgConfigurationException e)
{
Console.WriteLine(e.Message);
// exit application
}
I use this class to parse command line arguments, I've found it somewhere, but I can't remember where:
public class Arguments
{
// Variables
private StringDictionary Parameters;
// Constructor
public Arguments(string[] Args)
{
Parameters = new StringDictionary();
Regex Spliter = new Regex(#"^-{1,2}|^/|=|:",
RegexOptions.IgnoreCase | RegexOptions.Compiled);
Regex Remover = new Regex(#"^['""]?(.*?)['""]?$",
RegexOptions.IgnoreCase | RegexOptions.Compiled);
string Parameter = null;
string[] Parts;
// Valid parameters forms:
// {-,/,--}param{ ,=,:}((",')value(",'))
// Examples:
// -param1 value1 --param2 /param3:"Test-:-work"
// /param4=happy -param5 '--=nice=--'
foreach (string Txt in Args)
{
// Look for new parameters (-,/ or --) and a
// possible enclosed value (=,:)
Parts = Spliter.Split(Txt, 3);
switch (Parts.Length)
{
// Found a value (for the last parameter
// found (space separator))
case 1:
if (Parameter != null)
{
if (!Parameters.ContainsKey(Parameter))
{
Parts[0] =
Remover.Replace(Parts[0], "$1");
Parameters.Add(Parameter, Parts[0]);
}
Parameter = null;
}
// else Error: no parameter waiting for a value (skipped)
break;
// Found just a parameter
case 2:
// The last parameter is still waiting.
// With no value, set it to true.
if (Parameter != null)
{
if (!Parameters.ContainsKey(Parameter))
Parameters.Add(Parameter, "true");
}
Parameter = Parts[1];
break;
// Parameter with enclosed value
case 3:
// The last parameter is still waiting.
// With no value, set it to true.
if (Parameter != null)
{
if (!Parameters.ContainsKey(Parameter))
Parameters.Add(Parameter, "true");
}
Parameter = Parts[1];
// Remove possible enclosing characters (",')
if (!Parameters.ContainsKey(Parameter))
{
Parts[2] = Remover.Replace(Parts[2], "$1");
Parameters.Add(Parameter, Parts[2]);
}
Parameter = null;
break;
}
}
// In case a parameter is still waiting
if (Parameter != null)
{
if (!Parameters.ContainsKey(Parameter))
Parameters.Add(Parameter, "true");
}
}
// Retrieve a parameter value if it exists
// (overriding C# indexer property)
public string this[string Param]
{
get
{
return (Parameters[Param]);
}
}
}
I use it this way:
var cmdParams = new Arguments(args);
if (cmdParams["File"] != null && parametros["cmdParams"] == "Filename.txt) { }
Hope it helps!
Command line arguments can get complicated if there are different functions and arguments..
Best way is to tokenize your arguments, function switch examples are /p /a, or -h, -g etc...Your cmd arg parser looks for these tokens (pattern) - once found you know which cmd it is.. Have switch - case or any other mechanism for this. Also tokenise the other data arguments. Hence you have two sets of arguments - easy to manage.
I'm not sure if this question has been answered elsewhere and I can't seem to find anything through google that isn't a "Hello World" example... I'm coding in C# .NET 4.0.
I'm trying to develop a console application that will open, display text, and then wait for the user to input commands, where the commands will run particular business logic.
For example: If the user opens the application and types "help", I want to display a number of statements etc etc. I'm not sure how to code the 'event handler' for user input though.
Hopefully this makes sense. Any help would be much appreciated!
Cheers.
You need several steps to achieve this but it shouldn't be that hard. First you need some kind of parser that parses what you write. To read each command just use var command = Console.ReadLine(), and then parse that line. And execute the command... Main logic should have a base looking this (sort of):
public static void Main(string[] args)
{
var exit = false;
while(exit == false)
{
Console.WriteLine();
Console.WriteLine("Enter command (help to display help): ");
var command = Parser.Parse(Console.ReadLine());
exit = command.Execute();
}
}
Sort of, you could probably change that to be more complicated.
The code for the Parser and command is sort of straight forward:
public interface ICommand
{
bool Execute();
}
public class ExitCommand : ICommand
{
public bool Execute()
{
return true;
}
}
public static Class Parser
{
public static ICommand Parse(string commandString) {
// Parse your string and create Command object
var commandParts = commandString.Split(' ').ToList();
var commandName = commandParts[0];
var args = commandParts.Skip(1).ToList(); // the arguments is after the command
switch(commandName)
{
// Create command based on CommandName (and maybe arguments)
case "exit": return new ExitCommand();
.
.
.
.
}
}
}
I know this is an old question, but I was searching for an answer too. I was unable to find a simple one though, so I built InteractivePrompt. It's available as a NuGet Package and you can easily extend the code which is on GitHub. It features a history for the current session also.
The functionality in the question could be implemented this way with InteractivePrompt:
static string Help(string strCmd)
{
// ... logic
return "Help text";
}
static string OtherMethod(string strCmd)
{
// ... more logic
return "Other method";
}
static void Main(string[] args)
{
var prompt = "> ";
var startupMsg = "BizLogic Interpreter";
InteractivePrompt.Run(
((strCmd, listCmd) =>
{
string result;
switch (strCmd.ToLower())
{
case "help":
result = Help(strCmd);
break;
case "othermethod":
result = OtherMethod(strCmd);
break;
default:
result = "I'm sorry, I don't recognize that command.";
break;
}
return result + Environment.NewLine;
}), prompt, startupMsg);
}
This is easy enough, just use the Console.WriteLine and Console.ReadLine() methods. From the ReadLine you get a string. You could have a horrible if statement that validate this against known/expected inputs. Better would be to have a lookup table. Most sophisticated would be to write a parser. It really depends on how complex the inputs can be.
Console.WriteLine Console.ReadLine and Console.ReadKey are your friends. ReadLine and ReadKey waits for user input. The string[] args will have all of your parameters such as 'help' in them. The array is created by separating the command line arguments by spaces.
switch (Console.ReadLine())
{
case "Help":
// print help
break;
case "Other Command":
// do other command
break;
// etc.
default:
Console.WriteLine("Bad Command");
break;
}
If you're looking to parse commands that have other things in them like parameters, for example "manipulate file.txt" then this alone won't work. But you could for example use String.Split to separate the input into a command and arguments.
A sample:
static void Main(string[] args)
{
Console.WriteLine("Welcome to test console app, type help to get some help!");
while (true)
{
string input = Console.ReadLine();
int commandEndIndex = input.IndexOf(' ');
string command = string.Empty;
string commandParameters = string.Empty;
if (commandEndIndex > -1)
{
command = input.Substring(0, commandEndIndex);
commandParameters = input.Substring(commandEndIndex + 1, input.Length - commandEndIndex - 1);
}
else
{
command = input;
}
command = command.ToUpper();
switch (command)
{
case "EXIT":
{
return;
}
case "HELP":
{
Console.WriteLine("- enter EXIT to exit this application");
Console.WriteLine("- enter CLS to clear the screen");
Console.WriteLine("- enter FORECOLOR value to change text fore color (sample: FORECOLOR Red) ");
Console.WriteLine("- enter BACKCOLOR value to change text back color (sample: FORECOLOR Green) ");
break;
}
case "CLS":
{
Console.Clear();
break;
}
case "FORECOLOR":
{
try
{
Console.ForegroundColor = (ConsoleColor)Enum.Parse(typeof(ConsoleColor), commandParameters);
}
catch
{
Console.WriteLine("!!! Parameter not valid");
}
break;
}
case "BACKCOLOR":
{
try
{
Console.BackgroundColor = (ConsoleColor)Enum.Parse(typeof(ConsoleColor), commandParameters);
}
catch
{
Console.WriteLine("!!! Parameter not valid");
}
break;
}
default:
{
Console.WriteLine("!!! Bad command");
break;
}
}
}
}
This is very simplistic, but might meet your needs.
// somewhere to store the input
string userInput="";
// loop until the exit command comes in.
while (userInput != "exit")
{
// display a prompt
Console.Write("> ");
// get the input
userInput = Console.ReadLine().ToLower();
// Branch based on the input
switch (userInput)
{
case "exit":
break;
case "help":
{
DisplayHelp();
break;
}
case "option1":
{
DoOption1();
break;
}
// Give the user every opportunity to invoke your help system :)
default:
{
Console.WriteLine ("\"{0}\" is not a recognized command. Type \"help\" for options.", userInput);
break;
}
}
}
There is a C# nuget package called 'ReadLine' by 'tornerdo'. The statement ReadLine.Read(" prompt > "); prompts the user within options provided in CustomAutoCompletionHandler.PossibleAutoCompleteValues.
Additionally, you can change the CustomAutoCompletionHandler.PossibleAutoCompleteValues for each prompt. This ensures that the user get to choose an option from available\ supported list of options. Less error prone.
static void Main(string[] args)
{
Console.ForegroundColor = ConsoleColor.Cyan;
Console.WriteLine(" Note! When it prompts, press <tab> to get the choices. Additionally, you can use type ahead search.");
Console.ForegroundColor = ConsoleColor.White;
// Register auto completion handler..
ReadLine.AutoCompletionHandler = new CustomAutoCompletionHandler();
CustomAutoCompletionHandler.PossibleAutoCompleteValues = new List<string> { "dev", "qa", "stg", "prd" };
var env = CoverReadLine(ReadLine.Read(" Environment > "));
Console.WriteLine($"Environment: {env}");
}
private static string CoverReadLine(string lineRead) => CustomAutoCompletionHandler.PossibleAutoCompleteValues.Any(x => x == lineRead) ? lineRead : throw new Exception($"InvalidChoice. Reason: No such option, '{lineRead}'");
public class CustomAutoCompletionHandler : IAutoCompleteHandler
{
public static List<string> PossibleAutoCompleteValues = new List<string> { };
// characters to start completion from
public char[] Separators { get; set; } = new char[] { ' ', '.', '/' };
// text - The current text entered in the console
// index - The index of the terminal cursor within {text}
public string[] GetSuggestions(string userText, int index)
{
var possibleValues = PossibleAutoCompleteValues.Where(x => x.StartsWith(userText, StringComparison.InvariantCultureIgnoreCase)).ToList();
if (!possibleValues.Any()) possibleValues.Add("InvalidChoice");
return possibleValues.ToArray();
}
}