Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

A Converter (TryParse) Concept for Properties

0.00/5 (No votes)
15 Mar 2016 1  
There is a Parse and TryParse for fields, but they cannot be used for properties. Here is a concept to create TryParse that will work for properties.

Introduction

I was refactoring some code that was used to access AppSettings and figured I could do it better. The ConfigurationManager.AppSettings.Get method was being used to set a private field, and then that value was being used to set a property, and this was basically being set in a method.

Design

I decided that it would be better to do this in a static class, and that I could directly set the properties. However, the values had been in strings, and needed to be converted, and the Parse would not work on fields, even considering their disadvantage of not dealing with exceptions. I therefore started working on the idea of creating a TryParse method that was an extension method. I only needed to deal with a few types, so even though I had to create a method for each type, it was not too much work. As an added bonus, I decided to also create a method to deal with enumerations:

public static class Converters
{
 public static bool TryParseBool(this string str, bool defaultValue = false)
 {
  bool k;
  if (bool.TryParse(str, out k)) return k;
  return defaultValue;
 }
 public static int TryParseInt(this string str, int defaultValue = 0)
 {
  int k;
  if (int.TryParse(str, out k)) return k;
  return defaultValue;
 }
 public static double TryParseDouble(this string str, double defaultValue = 0)
 {
  double k;
  if (double.TryParse(str, out k)) return k;
  return defaultValue;
 }
 public static T TryParseEnum<T>(this string str, T defaultValue) where T : struct
 {
  T k;
  if (Enum.TryParse<T>(str, out k)) return k;
  return defaultValue;
 }
}

Another option is to create a generic that uses the TypeConverter, which means that on a single method is required as long as a TypeConverter exists for the class/struct:

public static T TryParse<T>(this string text, T defaultValue = default(T))
{
 // Get specific converter for the type
 TypeConverter converter = TypeDescriptor.GetConverter(typeof(T));
 // If there is a converter and conversion is valid
 return (converter?.IsValid(text) == true) ? (T)converter.ConvertFromInvariantString(text)
      : defaultValue;
}

In this case would have to have the Type to convert to in the angle brackets after the TryParse.

The static class that handled the appSettings became:

 public static class Constants
 {
  public static int DataVersion { get; } = ConfigurationManager.AppSettings
      .Get("DataVersion").TryParseInt();
  public static int SimulationPort { get; } = ConfigurationManager.AppSettings
      .Get(nameof(SimulationPort)).TryParseInt();
  public static double Value { get; } = ConfigurationManager.AppSettings
      .Get(nameof(Value)).TryParse<double>();
 }

Basically, one line for each of the appSettings. Notice that on the second property I use the nameof method instead of a string. I prefer using the same name, but obviously if different names are used, cannot use this method. The third property uses the generic version.

History

  • 03/15/2016: Initial version

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here