Reputation: 20474
I'm trying to write an overload for a typicall IsNumeric?
function, my intention is to accomplish two tasks calling one function (and of course optimizing the code to accomplish the task in the better way and in few lines of code, I don't know if my approach should be the better way but It's what I'm trying):
1st: Determine if the string value is numeric.
2nd: Determine if the numeric value is of the apropiate DataType. (Integer, Long, etc...) Long, etc...)
But I have two problems with this:
1st: The method "TryParse" is not found on the reflection search (I've tried a lot of binding combinations).
2nd: I don't know how to instance the DataType on the method parameters (See:
{Value, New T}
)
Here is my code:
Private Function StringIsNumericOf(Of T)(ByVal Value As String) As Boolean
Dim Method As MethodInfo =
GetType(T).GetMethod("TryParse", BindingFlags.Public)
If Method IsNot Nothing Then
Return Method.Invoke(Me, BindingFlags.Public, Nothing,
New Object() {Value, New T},
CultureInfo.InvariantCulture)
Else
MsgBox("Method not found.")
Return Nothing
End If
End Function
And here is an example usage of what I would like to expect:
' Expected result: False, it's a Double.
MsgBox(StringIsNumericOf(Of Long)("50.1D"))
' Expected result: False, it's an Int64.
MsgBox(StringIsNumericOf(Of Integer)("1L"))
' Expected result: True
MsgBox(StringIsNumericOf(Of Long)(CStr(Long.MaxValue)))
UPDATE:
Just a failed intent to solve the 1st problem, this is what I was trying:
Dim Method As MethodInfo =
GetType(T).GetMethod("TryParse",
BindingFlags.Public Or BindingFlags.Static,
Type.DefaultBinder,
New Type() {GetType(String), GetType(T)},
New ParameterModifier() {})
Upvotes: 1
Views: 71
Reputation: 20474
Just this is how looks the final work, thanks to @Jon Egerton answer.
''' <summary>
''' Determines whether an String is a valid numeric of the given type.
''' </summary>
''' <typeparam name="T">Indicates the numeric DataType</typeparam>
''' <param name="Value">Indicates the string value.</param>
''' <returns>
''' <c>true</c> if string is a valid numeric of the given type, <c>false</c> otherwise.
''' </returns>
''' <exception cref="Exception"></exception>
Private Function StringIsNumeric(Of T)(ByVal Value As String) As Boolean
Const MethodName As String = "TryParse"
Dim Result As Object = Nothing
Dim Method As MethodInfo =
GetType(T).GetMethod(MethodName,
BindingFlags.Public Or BindingFlags.Static,
Type.DefaultBinder,
New Type() {GetType(String), GetType(T).MakeByRefType()},
New ParameterModifier() {})
If Method IsNot Nothing Then
Return Method.Invoke(Me, BindingFlags.Public Or BindingFlags.Static,
Type.DefaultBinder,
New Object() {Value, Result},
CultureInfo.InvariantCulture)
Else
Throw New Exception(String.Format("Method '{0}' not found on '{1}' Type.",
MethodName, GetType(T).Name))
Return Nothing
End If
End Function
Upvotes: 0
Reputation: 41569
First problem: You need to use BindingFlags.Static
as well as BindingFlags.Public
, as TryParse
is a static method on the type.
Second problem, there are two versions of TryParse available. For example for integer there is:
public static bool TryParse(
string s,
out int result
)
and
To resolve this you have to pass in an array of types that matches the arguments to the overload you wish to invoke. In this case that is a String
, and a ByRef T
.
The following should bind the version you want:
GetType(T).GetMethod("TryParse",
BindingFlags.Public Or BindingFlags.Static,
Nothing,
New Type() {GetType(System.String), GetType(T).MakeByRefType()},
Nothing)
Upvotes: 2