Inspiriert von der hier von Charlie Brown veröffentlichten Lösung habe ich mithilfe von Reflection ein generisches TryParse erstellt, das optional den analysierten Wert ausgibt:
/// <summary>
/// Tries to convert the specified string representation of a logical value to
/// its type T equivalent. A return value indicates whether the conversion
/// succeeded or failed.
/// </summary>
/// <typeparam name="T">The type to try and convert to.</typeparam>
/// <param name="value">A string containing the value to try and convert.</param>
/// <param name="result">If the conversion was successful, the converted value of type T.</param>
/// <returns>If value was converted successfully, true; otherwise false.</returns>
public static bool TryParse<T>(string value, out T result) where T : struct {
var tryParseMethod = typeof(T).GetMethod("TryParse", BindingFlags.Static | BindingFlags.Public, null, new [] { typeof(string), typeof(T).MakeByRefType() }, null);
var parameters = new object[] { value, null };
var retVal = (bool)tryParseMethod.Invoke(null, parameters);
result = (T)parameters[1];
return retVal;
}
/// <summary>
/// Tries to convert the specified string representation of a logical value to
/// its type T equivalent. A return value indicates whether the conversion
/// succeeded or failed.
/// </summary>
/// <typeparam name="T">The type to try and convert to.</typeparam>
/// <param name="value">A string containing the value to try and convert.</param>
/// <returns>If value was converted successfully, true; otherwise false.</returns>
public static bool TryParse<T>(string value) where T : struct {
T throwaway;
var retVal = TryParse(value, out throwaway);
return retVal;
}
Es kann so genannt werden:
string input = "123";
decimal myDecimal;
bool myIntSuccess = TryParse<int>(input);
bool myDecimalSuccess = TryParse<decimal>(input, out myDecimal);
Update:
Auch dank der Lösung von YotaXP, die mir sehr gefällt, habe ich eine Version erstellt, die keine Erweiterungsmethoden verwendet, aber dennoch einen Singleton hat, wodurch die Notwendigkeit einer Reflexion minimiert wird:
/// <summary>
/// Provides some extra parsing functionality for value types.
/// </summary>
/// <typeparam name="T">The value type T to operate on.</typeparam>
public static class TryParseHelper<T> where T : struct {
private delegate bool TryParseFunc(string str, out T result);
private static TryParseFunc tryParseFuncCached;
private static TryParseFunc tryParseCached {
get {
return tryParseFuncCached ?? (tryParseFuncCached = Delegate.CreateDelegate(typeof(TryParseFunc), typeof(T), "TryParse") as TryParseFunc);
}
}
/// <summary>
/// Tries to convert the specified string representation of a logical value to
/// its type T equivalent. A return value indicates whether the conversion
/// succeeded or failed.
/// </summary>
/// <param name="value">A string containing the value to try and convert.</param>
/// <param name="result">If the conversion was successful, the converted value of type T.</param>
/// <returns>If value was converted successfully, true; otherwise false.</returns>
public static bool TryParse(string value, out T result) {
return tryParseCached(value, out result);
}
/// <summary>
/// Tries to convert the specified string representation of a logical value to
/// its type T equivalent. A return value indicates whether the conversion
/// succeeded or failed.
/// </summary>
/// <param name="value">A string containing the value to try and convert.</param>
/// <returns>If value was converted successfully, true; otherwise false.</returns>
public static bool TryParse(string value) {
T throwaway;
return TryParse(value, out throwaway);
}
}
Nennen Sie es so:
string input = "987";
decimal myDecimal;
bool myIntSuccess = TryParseHelper<int>.TryParse(input);
bool myDecimalSuccess = TryParseHelper<decimal>.TryParse(input, out myDecimal);