Introduction to generics in C# Part 3

Introduction

In the previous post on generics we looked at an example of reading application settings from a configuration file. Application settings come in key-value pairs where the value can be of different type: string, integer, boolean and various others. The generic ConfigurationReaderService helped us improve the non-generic code where the function caller had to take care of the type conversion and validation steps.

In this post we’ll further improve our code by looking into generic methods.

Generic methods, generic functions

So far we in this short series we have looked at generic classes, such as the one from the previous post:

public class ConfigurationReaderService<T>
{
}

We put the type parameter on the class declaration. Any time you construct a new ConfigurationReaderService you have to define its type parameter, like here:

ConfigurationReaderService<int> intConfigService = new ConfigurationReaderService<int>();
ConfigurationReaderService<bool> boolConfigService = new ConfigurationReaderService<bool>();

…depending on the type of the setting you’d like to retrieve. However, it feels a bit awkward to construct a new ConfigurationReaderService instance whenever we need to change the type parameter.

Fortunately for us we don’t need to set the entire class generic. We can make individual methods and functions generic as well using the same technique as how we attached the type parameter after the class declaration. We just need to do it on the function level instead.

The change on the ConfigurationReaderService class is minimal:

public class ConfigurationReaderService
{
	public T ReadConfigurationValue<T>(string key, T defaultValue, bool throwException = false)
	{
		var value = ConfigurationManager.AppSettings[key];
		if (value == null)
		{
			if (throwException)
			{
				throw new KeyNotFoundException("Key " + key + " not found.");
			}
			return defaultValue;
		}
		try
		{
			if (typeof(Enum).IsAssignableFrom(typeof(T)))
			{
				return (T)Enum.Parse(typeof(T), value);
			}
			return (T)Convert.ChangeType(value, typeof(T));
		}
		catch (Exception ex)
		{
			if (throwException)
			{
				throw ex;
			}
			return defaultValue;
		}
	}
}

We just put the type parameter after the function name instead of the class name, that’s it.

Now it’s enough to construct one ConfigurationReaderService instance and call its ReadConfigurationValue multiple times:

ConfigurationReaderService configService = new ConfigurationReaderService();
int maxLoops = configService.ReadConfigurationValue<int>("max-loops", 50);
Debug.WriteLine(string.Format("Max loops: {0}", maxLoops));
bool cheatModeOn = configService.ReadConfigurationValue<bool>("cheat-mode-on", false);
Debug.WriteLine(string.Format("Cheat mode on: {0}", cheatModeOn));

This produces the same output in the debug window as before:

Max loops: 10
Cheat mode on: True

While we’re at it we can demonstrate that even interfaces can have generic functions:

public interface IConfigurationRepository
{
	T ReadConfigurationValue<T>(string key, T defaultValue, bool throwException = false);
}

Our ConfigurationReaderService class can then implement this interface:

public class ConfigurationReaderService : IConfigurationRepository

In the next part we’ll look into setting multiple type parameters on the class or function.

View all various C# language feature related posts here.

Advertisement

About Andras Nemes
I'm a .NET/Java developer living and working in Stockholm, Sweden.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

Elliot Balynn's Blog

A directory of wonderful thoughts

Software Engineering

Web development

Disparate Opinions

Various tidbits

chsakell's Blog

WEB APPLICATION DEVELOPMENT TUTORIALS WITH OPEN-SOURCE PROJECTS

Once Upon a Camayoc

Bite-size insight on Cyber Security for the not too technical.

%d bloggers like this: