Chcę przekonwertować ciąg na typ ogólny, taki jak int
lub date
lub long
na podstawie ogólnego typu zwracanego.
Zasadniczo funkcja taka jak Parse<T>(String)
ta zwraca element typu T
.
Na przykład, jeśli przekazano int, funkcja powinna działać int.parse
wewnętrznie.
c#
string
parsing
type-conversion
Karim
źródło
źródło
IConvertable
czy nie należy również ograniczaćT
, tj.T ChangeType<T>(this object obj) where T : IConvertable
?obj
musi byćIConvertible
, ale nie ma sposobu, aby to określić w czasie kompilacji.Wygląda na to, że jestem już za późno na odpowiedź w tym wątku. Ale oto moja realizacja:
Zasadniczo utworzyłem metodę Extention dla klasy Object. Obsługuje wszystkie typy, tj. Dopuszcza wartość null, klasy i strukturę.
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; }
źródło
TypeDescriptor
dla typów dopuszczających wartość null iConvert.ChangeType
dla typów nie dopuszczających wartości null? Całytry
blok można zredukować tylko doTypeConverter
2 wierszy kodu i będzie działał zarówno dla wartości null, jak i non-nullable.System.Convert.ChangeType
nie konwertuje na żaden typ. Pomyśl o następujących kwestiach:Te konwersje są możliwe dzięki tej implementacji ChangeType .
źródło
czystsza wersja odpowiedzi Pranaya
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); } }
źródło
W .NET istnieje kilka konwencji konwertowania obiektów jednego typu na inny.
Ale te metody są znacznie wolniejsze niż typowe
T.Parse(string)
, powodują boksowanie i wymagają wielu alokacji za każdym razem, gdy chcesz przekonwertować pojedynczą wartość.W przypadku ciągu ValueString zdecydowałem się znaleźć odpowiednią, statyczną metodę analizy typu przy użyciu odbicia, zbudować wyrażenie lambda wywołujące ją i buforować skompilowanego delegata do wykorzystania w przyszłości (przykład można znaleźć w tej odpowiedzi ).
Jeśli typ nie ma odpowiedniej metody analizy, odwołuje się do sposobów, o których wspomniałem powyżej (zobacz sekcję dotyczącą wydajności w pliku Readme).
var v = new ValueString("15"); // struct var i = v.As<int>(); // Calls int.Parse.
źródło