There is a problem when viewing the company Project code: WinForm interface has a lot of information to fill out, submitted to the background server update, but the data of the legal verification and value conversion is not too flattering, a bunch of if judgments and conversion, then think whether can expand a method out, figure out a train of thought, record down to discuss together with everybody , there is the wrong place also please correct me.
Design ideas:
1. Since most of the data values are obtained from the TextBox control, you can extend a generic method to get the value directly from the converted data type, like this,
var value = this.txtsample.getvalue<int> ();
2. You can pass in a delegate to handle a conversion failure, and overload this method to provide a default action.
Okay, here we are:
1. Create a TextBox type extension method
Explanation for MSDN: extension methods enable you to add a method to an existing type without creating a new derived type, recompiling, or otherwise modifying the original type. An extension method is a special static method, but can be invoked just like an instance method on an extended type. For client code written in C # and Visual Basic, there is no significant difference between calling an extension method and invoking a method that is actually defined in a type.
Extension methods are defined as static methods, but they are invoked through instance method syntax. Their first argument specifies which type the method acts on, and the parameter is prefixed with the This modifier. The extension method is only in scope when you explicitly import the namespace into the source code with the using directive.
Note: The extension method is defined inside a nested, non-generic static class
2. Because the conversion type is unknown, but is a value type, it is designed with a generic method, plus a strut generic constraint, which is implemented by passing in an action delegate because it allows the customization to handle the operation when the conversion fails, as follows:
Copy Code code as follows:
public static TResult getvalue<tresult> (this textbox textbox, Action<textbox> failed)
where tresult:struct
{
var type = typeof (TResult);
var method = type. GetMethod ("TryParse", new type[] {typeof (String), Type. Makebyreftype ()});
var parameters = new Object[] {textbox.text, default (TResult)};
If conversion fails, execute failed
if (!) ( BOOL) method. Invoke (null, parameters))
{
Failed (TextBox);
throw new InvalidCastException ("The input value is not in the correct format, please check the input value.") ");
}
Return (TResult) parameters[1];
}
Here the reflection mechanism is used to invoke the type of T.tryparse (string param, out T value), such as Int32.TryParse (string param,out Int32 value), which requires Note that:
(1). GetMethod () method, you must pass in the appropriate parameters (the signature of the method to reflect) to determine the method unique, such as encountering overloading (more common), otherwise the return value is null, in the signature of the method, if the parameter with the ref or out keyword, Type types need to be added. Makebyreftype (), as above.
(2). After you get a unique method instance, you can pass in the appropriate parameters, invoke the Invoke method to implement the invocation of the method, Methodinfo.invoke (Object obj, object[] Parameters) method The first parameter calls the method for reflection Object, if it is a static method (such as this example), you can pass in NULL, the second parameter is the parameter of the method, and the order must be consistent with the method signature.
(3). The method parameter is provided with the ref and out keyword, which is obtained by an array of arguments. As in this example: Parameters[1]
3. Define a delegate for a transformation failure operation
C # Built-in encapsulation There are two kinds of delegates, action and Func delegates, and there are many overloaded versions, parameters can be more than 10, so do not worry about parameter problems. Where the action delegate has no return value, is a void type, and the Func delegate has a return value, such as FUNC<T,TRESULT>, which is common in LINQ operations, in which there is no need to return a value, so the action delegate is used because the operation failed to handle the conversion , the textbox is processed as a parameter to the delegate, as shown in the code, and processed when the conversion fails:
If conversion fails, execute failed
if (!) ( BOOL) method. Invoke (null, parameters))
Failed (TextBox);
In this brief introduction of the delegate: the delegate is actually a type, through the Decompile tool can be seen, when the construction of a delegate to pass a method, in fact, will pass into two parameters (TARGET,METHODPTR), the target parameter is called the instance of the method, if the static method, is null, Methodptr for the memory address of the incoming method (storing this information in the metadata), Faild (TextBox) surface is not very good understanding, why an object with a parameter behind, in fact, the C # compiler for us to do a lot of work, in essence for the faild. Invoke (TextBox), so it looks good. The understanding delegate is a type that invokes the method registered by the delegate through the Faild delegate object.
4. To create an overloaded version:
Defines a default conversion failure operation with a lambda expression, prompts the message if the conversion fails, and selects all and navigates to the input box.
Copy Code code as follows:
public static TResult getvalue<tresult> (this textbox textbox, bool Isshowerror)
where tresult:struct
{
Return getvalue<tresult> (TextBox, p =>
{
if (isshowerror)
{
P.focus ();
P.selectall ();
MessageBox.Show ("Input value is not in the correct format, please re-enter!") ",
"Hint-value type:" + typeof (TResult). Name,
MessageBoxButtons.OK, messageboxicon.warning);
}
});
}
Copy Code code as follows:
Default version, calling the last overloaded method
public static TResult getvalue<tresult> (this textbox textbox)
where tresult:struct
{
Return getvalue<tresult> (TextBox, true);
}
5. Experiment Test:
New WinForm program, the interface as shown in the picture:
Background code:
Copy Code code as follows:
private void Btnconvert_click (object sender, EventArgs e)
{
Try
{
var intvalue = txtint.getvalue<int> ();
var floatvalue = txtfloat.getvalue<float> ();
var datetimevalue = txtdatetime.getvalue<datetime> ();
var doublevalue = txtdouble.getvalue<double> ();
}
catch (Exception) {}
}
If the input value is illegal, an error is prompted, as shown in the figure: