Beschreibung:
Im laufe der Zeit hat sich bei mir die statische Klasse InputValidator mit Methoden zur Prüfung von Eingaben angesammelt, die mir schon oft geholfen hat. Mit der Zeit kommen ab und an mal neue Methoden hinzu, und sie ist auch nicht gerade riesig.
Bis zum Zeitpunkt als ich begonnen habe mit der Klasse zu arbeiten, habe ich die Prüfungen immer wieder neu geschrieben, für jede Anwendung. Auch wenn der nutzen nur in Hinsicht der wiederverwendbarkeit liegt, möchte ich euch die Klasse nicht vorenthalten. Die Validierung eigener Typen habe ich entfernt. Somit bleibt eine überschaubare Menge an Typen übrig.
Update (18.11.2011): Die Klasse wurde von mir so geändert, dass die Validierungsmethode generisch ist, und eine Verwendung als Erweiterungsmethode möglich ist.
public static class InputValidator
{
/// <summary>
/// Method to check if a string can be converted to a given type
/// </summary>
/// <typeparam name="T">the type</typeparam>
/// <param name="input">the input</param>
/// <returns>true if the string can be converted to the given type</returns>
public static bool CanConvertTo<T>(this string input)
{
Object converted;
try
{
converted = Convert.ChangeType(input, typeof(T));
}
catch
{
converted = null;
}
return converted != null;
}
}
Schlagwörter: Eingabevalidigierung, Typprüfung, Datentypen, input validation, InputValidator
Wissen ist nicht alles. Man muss es auch anwenden können.
PS Fritz!Box API - TR-064 Schnittstelle | PS EventLogManager |
Hallo inflames2k,
cool wäre das ganze noch als Erweiterungsmethoden - also überall ein this
vor das String-Argument.
mfG Gü
Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.
"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"
// Codeoptimierung an
/// <summary> /// Method to check if the input is Int32 /// </summary> /// <param name="input">the input</param> /// <returns>true if the input is Int32</returns> public static bool IsInt32(string input) { Int32 value; return Int32.TryParse(input, out value); }
// Codeoptimierung aus
cool wäre das ganze noch als Erweiterungsmethoden - also überall ein this vor das String-Argument.
Oder man macht das ganze generisch und hat nur noch eine Methode.
InputValidator.IsTypeOf<int>("123");
Grüße,
dispose
Hi zusammen,
leider gibt es für TryParse kein Interface, um das ganze generisch zu machen (außer intern dann per Reflection auf die Methode zuzugreifen).
Interface wäre cool... aber ist hier ohnehin nicht notwendig.
public static bool CanParseTo<T>(this string input) where T:struct
{
string typeIdentifier = typeof (T).Name;
switch(typeIdentifier)
{
case "Int32":
Int32 value;
return Int32.TryParse(input, out value);
// usw...
default:
throw new NotSupportedException("The Type '" + typeIdentifier + "' is not supported.");
}
}
Aber irgendwie nicht meine Vorstellung von generisch 🤔
Dann doch lieber per Reflection, so daß man auch für eigene Datentypen einfach nur eine "TryParse"-Methode anbieten müßte.
Ich habe bei mir noch folgenden Code-Schnippsel entdeckt, welcher hier passen würde:
public static T ConvertTo<T>(this object value)
{
if (value != null)
{
Type targetType = typeof(T);
TypeConverter converter = TypeDescriptor.GetConverter(value);
if (converter != null)
{
if (converter.CanConvertTo(targetType))
{
return (T)converter.ConvertTo(null, CultureInfo.InvariantCulture, value, targetType);
}
}
}
return null;
}
Gruß
Björn
Ich möchte in den Code von Björn nicht eingreifen, aber ein return null
ist hier aufgrund von T nicht möglich. Stattdessen müsste default(T)
verwendet werden.
@Björn,
das funktioniert leider nicht so gut, da eine Lexikalische Konvertierung mit Typeconverter nicht geht.
Ich hätte das so:
public static bool isType<T>(string value)
{
// is everytime a string
if (typeof(T) == typeof(string)) return true;
// else try to find a TryParse of the output type
MethodInfo x = default(T).GetType().GetMethod("TryParse", new Type[]{typeof(string),typeof(T).MakeByRefType()});
// if a TryParse found, return the result. Othwerwise return false
if (x != null)
return (bool)x.Invoke(new object(), new object[] { value, default(T) });
else return false;
}
gelöst
Grüße,
PS: Verbesserungen sind gerne gesehen
@panicJonny
Ist zwar schön kurz gehalten. Aber aus meiner Sicht ist Reflection hier ein Fall von mit Kanonen auf Spatzen geschossen.
Bis auf den Try-Catch gefällt mir eigentlich folgende Variante:
/// <summary>
/// Method to validate an input
/// </summary>
public static class InputValidator
{
/// <summary>
/// Method to check if a string can be converted to a given type
/// </summary>
/// <typeparam name="T">the type</typeparam>
/// <param name="input">the input</param>
/// <returns>true if the string can be converted to the given type</returns>
public static bool CanConvertTo<T>(this string input)
{
Object converted;
try
{
converted = Convert.ChangeType(input, typeof(T));
}
catch
{
converted = null;
}
return converted != null;
}
}
Wissen ist nicht alles. Man muss es auch anwenden können.
PS Fritz!Box API - TR-064 Schnittstelle | PS EventLogManager |
Immerhin hab ich damit viele Spatzen getroffen 😄
Ich geb an der Stelle auch einfach mal zu, dass das oben mein erster echter Versuch in Sachen Reflection war. Hat mir viel Spaß gemacht, das zu basteln und als ich gesehen habe, dass der Beitrag schon älter ist, wollte ich das eigentlich nicht posten.
Aber mal interessant zu sehen, wie du dich von deinem ersten Post weiterentwickelt hast ^^.
Grüße,