public static void ParseArgs (string [] args) { // Arguments are assumed to come in pairs, e.g.: // program /arg1 arg_value1 /arg2 arg_value2 Validate.True ("Number of arguments is even", 0 == (args.Length & 1)); MethodInfo method_info; string convert_method; object [] parameters = new object [1]; Type [] string_type = { typeof (String) }; // Get the type for where ever this is being called // There must be a better way to do this Type this_type = new StackTrace ().GetFrame (0).GetMethod ().ReflectedType; try { // Loop through each argument pair (i += 2), assumed format is: // program /arg1 arg_value1 /arg2 arg_value2 // Other formats are not supported. arg1, arg2, etc are assumed // to be static properties for this_type. for (int i = 0; i < args.Length; i += 2) { // Trim the leading slash on the property name Validate.True ("Arguments start with a slash(/)", args [i] [0].Equals ('/')); string prop_name = args [i].TrimStart ('/'); // Get the property associated with this argument. We don't // have an instance, so only static properties are appropriate. PropertyInfo pi = this_type.GetProperty (prop_name, BindingFlags.IgnoreCase | BindingFlags.Static | BindingFlags.SetProperty | BindingFlags.Public); // If there is no match then just continue if (null == pi) continue; // Get the Setter mthod for this property method_info = pi.GetSetMethod (); // Conversion is based on the Convert class. // Here we try to assemble the name for the appropriate // method of Convert. Methods are of the form "To____(String)" // where "____" is the Type we are trying to convert the // string two. convert_method = "To" + pi.PropertyType.Name; // Get the Convert method MethodInfo m = typeof (Convert).GetMethod ( convert_method, string_type); // We will pass the current arg_value to the Convert method parameters [0] = args [i + 1]; // Invoke the convert method. The result will be passed to // the property's Setter method. parameters [0] = m.Invoke (typeof (Convert), parameters); // Invoke the setter method on this_type method_info.Invoke (this_type, parameters); } } catch (Exception ex) { new LoggedException (ex, "Failed to parse command line arguments").Log (); } }
Ramblings of a person writing code that thinks too much about everything and needs a place to put it all
Tuesday, March 16, 2010
Using Reflection to Automatically Parse Command Line Arguments
It's been a while since I wrote a real command line application (long before C# got reflection) and haven't had to parse command line arguments in quite some time. Here is my new ParseArgs() function using reflection. The basic assumption is that arguments are being used to set static Properties of the entry point class.
Labels:
C#,
Reflection,
Write-Less-Code
Subscribe to:
Post Comments (Atom)
Hi Jerry! I am wondering if you even still maintain or think about this site anymore... but thank you very much for this and your previous posts.
ReplyDeleteDid you ever get around to finishing this framework? I am looking to do something very similar right now. I work in automation. Are you still performing automated testing as part of your duties?
-Nelson (brownnrl _a_t_ -->) (gmail)