How to Really write a Server Control in ASP.Net
- November 13, 2013
Find Missing Dependency DLLs on Win 7
- March 5, 2012
Nullable TryParse
- May 26, 2011
Diff SQL Server Stored Procedures, November 15, 2010
Reporting Services Extranet Access, March 16, 2010
Case of the missing WaitCursor, January 7, 2009
Simple Submit Button Disable, December 9, 2009
An Efficient Memory Stream, September 29, 2009
Approach Plate Download - May 14, 2009
WPF Binding - Async Web Services - April 10, 2009
Developing the Blog
- April 4, 2009
|
|
I did some looking around for a good helper function for using TryParse to return a nullable type. There were a couple
of examples, but nothing where you weren't writing a function for each type that had a TryParse. Even the example with
generics had a specific implementation for each type.
So, I have written a generic version which uses reflection to try and call the generic type's TryParse. In this version,
I just restrict the generic type to any value type, and return null if the type does not have a TryParse. But you could help protect calling
with an invalid type, and get a compiler error instead, by limiting to the specific types which have a TryParse.
// helper function for nullable TryParse.
Only works with value types
private
static T? TryParse<T>(string
i_value) where T :
struct
{
// since the second parm for a TryParse is an out
parameter, we
// need to pass an object array with space reserved
for the
// out value.
I am passing its default value just to make me
// feel comfortable, but null would have worked just
as well
object [] a_parms = new
object[] { i_value,
default(T) };
try
{
// try and call a TryParse off the static members of
this class. If anything fails,
// like the method does not exist, then they will get
null
if ((bool)typeof(T).InvokeMember("TryParse",
BindingFlags.Public |
BindingFlags.Static |
BindingFlags.InvokeMethod,
null, null,
a_parms))
return a_parms[1]
as T?;
}
catch {}
return null;
}
DateTime? a_startDate = TryParse<DateTime>("1/1/11");
decimal? a_foo = TryParse<Decimal>("123.456");
Addendum:
I came across the
IConvertible interface and ChangeType
function in the .Net 4.0 Libraries this evening. It simplifies the above
code, and even allows you to pass things other than strings (any class which
inplements
IConvertible will do, including any
complex class you write to implement it):
private
static T? TryParse<T>(IConvertible
i_value) where T :
struct
{
try
{
return (T)Convert.ChangeType(i_value,
typeof(T));
}
catch { }
return null;
}
So, not only do the above TryParse<T>(string) calls work, you can also do things
like:
Boolean? a_res = TryParse<Boolean>(1);
int? a_res3 = TryParse<int>(false);
But the power still lies in converting strings, as in user input which may or
may not exist.
|