Eu quero converter uma string em um tipo genérico como int
ou date
ou com long
base no tipo de retorno genérico.
Basicamente, uma função como Parse<T>(String)
essa retorna um item do tipo T
.
Por exemplo, se um int foi passado, a função deve ser executada int.parse
internamente.
c#
string
parsing
type-conversion
Karim
fonte
fonte
IConvertable
, você também não deve restringir oT
, isto éT ChangeType<T>(this object obj) where T : IConvertable
?obj
deve serIConvertible
, mas não há como especificar isso em tempo de compilação.Bem, parece que estou muito atrasado para responder a esta discussão. Mas aqui está minha implementação:
Basicamente, criei um método de extensão para a classe Object. Ele lida com todos os tipos, ou seja, anulável, classes e estrutura.
public static T ConvertTo<T>(this object value) { T returnValue; if (value is T variable) returnValue = variable; else try { //Handling Nullable types i.e, int?, double?, bool? .. etc if (Nullable.GetUnderlyingType(typeof(T)) != null) { TypeConverter conv = TypeDescriptor.GetConverter(typeof(T)); returnValue = (T) conv.ConvertFrom(value); } else { returnValue = (T) Convert.ChangeType(value, typeof(T)); } } catch (Exception) { returnValue = default(T); } return returnValue; }
fonte
TypeDescriptor
para tipos anuláveis eConvert.ChangeType
não anuláveis? Todo essetry
bloco pode ser reduzido a apenasTypeConverter
2 linhas de código e funcionará para ambos, anulável e não anulável.System.Convert.ChangeType
não converte para nenhum tipo. Pense no seguinte:Essas conversões são possíveis com esta implementação de ChangeType .
fonte
versão mais limpa da resposta de Pranay
public static T ConvertTo<T>(this object value) { if (value is T variable) return variable; try { //Handling Nullable types i.e, int?, double?, bool? .. etc if (Nullable.GetUnderlyingType(typeof(T)) != null) { return (T)TypeDescriptor.GetConverter(typeof(T)).ConvertFrom(value); } return (T)Convert.ChangeType(value, typeof(T)); } catch (Exception) { return default(T); } }
fonte
Existem algumas convenções no .NET para converter objetos de um tipo em outro.
Mas esses métodos são muito mais lentos do que o normal
T.Parse(string)
, causam encaixotamento e envolvem muitas alocações cada vez que você deseja converter um único valor.Para ValueString , escolhi encontrar um método de análise estática adequado do tipo usando reflexão, construir uma expressão lambda chamando-o e armazenar em cache o delegado compilado para uso futuro (veja esta resposta para um exemplo).
Ele também retorna para as maneiras que mencionei acima se o tipo não tiver um método de análise adequado (consulte a seção de desempenho no leiame).
var v = new ValueString("15"); // struct var i = v.As<int>(); // Calls int.Parse.
fonte