Click here to Skip to main content
15,868,164 members
Articles / Programming Languages / C#
Tip/Trick

A Converter (TryParse) Concept for Properties

Rate me:
Please Sign up or sign in to vote.
4.64/5 (12 votes)
15 Mar 2016CPOL1 min read 14.4K   13   8   2
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:

C#
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:

C#
 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, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) Clifford Nelson Consulting
United States United States
Has been working as a C# developer on contract for the last several years, including 3 years at Microsoft. Previously worked with Visual Basic and Microsoft Access VBA, and have developed code for Word, Excel and Outlook. Started working with WPF in 2007 when part of the Microsoft WPF team. For the last eight years has been working primarily as a senior WPF/C# and Silverlight/C# developer. Currently working as WPF developer with BioNano Genomics in San Diego, CA redesigning their UI for their camera system. he can be reached at qck1@hotmail.com.

Comments and Discussions

 
QuestionOnly one method Pin
Troopers15-Mar-16 21:49
Troopers15-Mar-16 21:49 
You could implement only one method to try parse :
C#
/// <summary>
/// Try to parse a string
/// </summary>
/// <param name="text">Text to parse</param>
/// <param name="type">Type of result</param>
/// <param name="result">Result</param>
/// <returns>True if string was parsed, else false</returns>
public static bool TryParse(this string text, Type type, out object result)
{
	// Get specific converter for the type
	TypeConverter converter = TypeDescriptor.GetConverter(type);
	// If there is a converter and conversion is valid
	if(converter != null && converter.IsValid(text))
	{
		// Convert
		result = converter.ConvertFromInvariantString(text);
		return true;
	}
	else
	{
		// Return the default value of the type
		result = type.GetDefaultValue();
		return false;
	}
}

/// <summary>
/// Get the default value of a type
/// </summary>
/// <param name="type">Type</param>
/// <returns>Default value</returns>
public static object GetDefaultValue(this Type type)
{
	return type.IsValueType ? Activator.CreateInstance(type) : null;
}

AnswerRe: Only one method Pin
Clifford Nelson16-Mar-16 7:58
Clifford Nelson16-Mar-16 7:58 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.