Convertendo valores para tipo genérico. (#csharp #dotnet #dev)

Overview
Explorando um pouco mais o mundo da programação C#, hoje trazemos um truque incrivelmente útil: como converter uma variável para um tipo genérico, valendo-se do conceito de generics
Abaixo mostro como converter uma variável qualquer para um tipo genérico (generics <T>).
Antes de começar, vale lembrar que o método que vou mostrar aqui funciona apenas para classes que implementam a interface IConvertible. Até o momento da criação deste post, as seguintes classes implementam ele nativamente:
- System.Boolean
- System.Byte
- System.Char
- System.DateTime
- System.DBNull
- System.Decimal
- System.Double
- System.Enum
- System.Int16
- System.Int32
- System.Int64
- System.SByte
- System.Single
- System.String
- System.UInt16
- System.UInt32
- System.UInt64
A conversão é bem simples, basta utilizar a classe Convert:
1using System;
2...
3var converted = (T)Convert.ChangeType(originalValue, typeof(T));
Aproveitando o embalo do ultimo post, abaixo está o exemplo aplicado a um método de extensão de HttpRequest:
1public static class HttpRequestExtensions
2{
3 /// <summary>
4 /// Tries to extract a value from the request header.
5 /// If the key is not found, will return default value for the required type.
6 /// </summary>
7 /// <param name="req">Http request</param>
8 /// <param name="key">header key</param>
9 /// <param name="defaultValue">default value to be returned when the key is not found</param>
10 /// <typeparam name="T">return type</typeparam>
11 /// <returns>extracted (or default) value</returns>
12 public static T GetParsedHeader<T>(this HttpRequest req, string key, T defaultValue = default)
13 {
14 return req.Headers.TryGetValue(key, out var value)
15 ? (T) Convert.ChangeType(value.ToString(), typeof(T))
16 : defaultValue;
17 }
No método acima, tento extrair e converter o valor. Se não der certo, ou seja, se a chave não existir no header, será retornado o valor padrão (default) do tipo informado (T). Talvez fosse melhor lançar uma exception, mas isso vai variar de acordo com a necessidade.
Ainda sobre a implementação acima, faço a conversão do valor para string (value.ToString()), pois o valor retornado pelo TryGetValue é um StringValue e ele não implementa IConvertible, mas string implementa.
Espero ter ajudado.