I've made a pretty standard console in which you type a command and it does something. However, the issue that comes to my mind is scaling: if I want to add hundreds of commands, I have to manually add a new Command instance for each one individually, which is... less than ideal.
The full code is stored in this GitHub repository.
Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ConsolePlus.Commands;
namespace ConsolePlus
{
    public class Program
    {
        /// <summary>
        /// The version of the program.
        /// </summary>
        public const string Version = "1.0.0.0";
        public static CommandRegistry<Command> Registry = new CommandRegistry<Command>();
        /// <summary>
        /// The application's entry point.
        /// </summary>
        /// <param name="args">The command-line arguments passed to the program.</param>
        public static void Main(string[] args)
        {
            CommandHandler.RegisterCommands();
            Console.WriteLine("ConsolePlus v." + Version);
            while (true)
            {
                Console.Write(">>> ");
                string line = Console.ReadLine();
                List<string> parts = line.Split(' ').ToList<string>();
                string commandName = parts[0];
                parts.RemoveAt(0);
                string[] commandArgs = parts.ToArray<string>();
                try
                {
                    string result = Registry.Execute(commandName, commandArgs);
                    if (result != null)
                    {
                        Console.WriteLine("[{0}] {1}", commandName, result);
                    }
                }
                catch (CommandNotFoundException)
                {
                    Console.WriteLine("[ConsolePlus] No such command.");
                }
            }
        }
    }
}
CommandRegistry.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsolePlus
{
    public class CommandRegistry<T>
        where T : ICommand
    {
        private Dictionary<string, T> register;
        public CommandRegistry()
        {
            register = new Dictionary<string, T>();
        }
        public CommandRegistry(params T[] commands)
            : this()
        {
            foreach (T command in commands)
            {
                register.Add(command.Name, command);
            }
        }
        public T GetCommand(string name)
        {
            if (register.ContainsKey(name))
            {
                return register[name];
            }
            else
            {
                throw new CommandNotFoundException(name);
            }
        }
        public string Execute(string name, string[] args)
        {
            if (register.ContainsKey(name))
            {
                return register[name].Execute(args);
            }
            else
            {
                throw new CommandNotFoundException(name);
            }
        }
        public void RegisterCommand(T command)
        {
            register.Add(command.Name, command);
        }
    }
}
ICommand.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsolePlus
{
    public interface ICommand
    {
        string Name { get; set; }
        string HelpText { get; set; }
        bool IsPrivileged { get; set; }
        string Execute(string[] args);
    }
}
Command.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsolePlus
{
    public class Command : ICommand
    {
        public string Name { get; set; }
        public string HelpText { get; set; }
        public bool IsPrivileged { get; set; }
        private Func<string[], string> method;
        public Command(string name, bool privileged, string help, Func<string[], string> commandMethod)
        {
            Name = name;
            IsPrivileged = privileged;
            HelpText = help;
            method = commandMethod;
        }
        public string Execute(string[] args)
        {
            return method.Invoke(args);
        }
    }
}
CommandHandler.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsolePlus.Commands
{
    public class CommandHandler
    {
        public static List<Command> AllCommands = new List<Command>
        {
            new Command("clear", false, ClearCommand.HelpText, ClearCommand.CommandMethod),
            new Command("exit", false, ExitCommand.HelpText, ExitCommand.CommandMethod)
        };
        public static void RegisterCommands()
        {
            foreach (Command command in AllCommands)
            {
                Program.Registry.RegisterCommand(command);
            }
        }
    }
}
And just for illustration (the other *Command classes are very similar):
ClearCommand.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsolePlus.Commands
{
    class ClearCommand
    {
        public static string HelpText = "Clears the console screen.";
        public static string CommandMethod(string[] args)
        {
            Console.Clear();
            return null;
        }
    }
}
At the moment, to add another command, I have to create another class and add another new Command line to the CommandHandler.RegisterCommands method - not ideal. Reviews of this specifically, and if there are any better ways to do this, would be very useful - though of course, any review is a good thing.

