Managing Command Line Arguments
I've been spending many of my recent developer cycles writing console applications to perform various tasks in an ETL process. And yes, before you ask, I had started out initially modeling my ETL process with SSIS - and while I could eventually get it to do what I wanted, at the end of the day, regular code was a more direct and expressive syntax for describing my process.
Anyway, one of the recurring things that I found myself having to do as I was writing these little command line apps was parsing various command line arguments - whether they were positional parameters, optional (named) parameters or switches. I refactored that args-managing logic out into its own class and wanted to share it with you in the case that you find yourself rewriting similar code in your applications. One of the things that you'll notice is that the error handling code is pretty sparse, and I could have made it even more robust by supporting different arg formats instead of hard-coding the delimiter characters. Perhaps one day...
internal class CommandLineArgs
{
private readonly IEnumerable<string> _args;
public CommandLineArgs(IEnumerable<string> args) {
_args = args;
}
public bool GetSwitch(string switchName) {
var swt =
_args.FirstOrDefault(
a =>
a.Equals("/" + switchName, StringComparison.InvariantCultureIgnoreCase) ||
a.Equals("-" + switchName, StringComparison.InvariantCultureIgnoreCase));
return !string.IsNullOrEmpty(swt);
}
public T ParseParam<T>(string param) {
var paramString = _args.FirstOrDefault(s => s.StartsWith(string.Format("/{0}:", param)));
if (string.IsNullOrEmpty(paramString))
throw new ArgumentException(
"The requested argument was not found in the command line arguments.", param);
var paramValueString = paramString.Split(':')[1];
return GetTypedVal<T>(paramValueString);
}
public T GetArgAt<T>(int position) {
var val = _args.ElementAt(position);
return GetTypedVal<T>(val);
}
private T GetTypedVal<T>(string val) {
try {
return (T) Convert.ChangeType(val, typeof (T));
}
catch (Exception ex) {
throw new ArgumentException(
"Argument value [" + val + "] could not be parsed into type [" + typeof (T).Name + "].",
ex);
}
}
}
I am currently the Editor-in-Chief for MSDN Magazine. I joined Microsoft in 2006 as a product planner with the certification team at Microsoft Learning. Prior to that, I spent my career as a developer and later as an architect. My main technology passions include pretty much anything on language theory, agile development, and service-oriented architecture.