Lazy TryParse
This is my second attempt on the TryParse with the C# 3.0 Extension Methods.
I just noticed that I am copy-pasting a lot of the Integer and Boolean parsing in my current project. Maybe I just don't know any better but I ended up using TryParse this way:
int intParsed;
value= int.TryParse(reader["Value"].ToString(), out intParsed) ? intParsed : 0;
or a little bit simpler:
int intParsed= int.TryParse(reader["Value"].ToString(), out intParsed) ? intParsed : 0;
I will appreciate if somebody would show me simpler solution but so far it is as it is. I am stuck with .NET 2.0 for now, but would it be 3.5, I'd put together an extension method. It started as a pretty simple extension of a Int32 type, but quickly evolved to the more generic solution, which uses some kind of Duck Typing guessing:
public static class TryParseExtenderIt is not the prettiest code but does the job. Return statement assumes that types which expose TryParse are able to cast the Object type to themselves. Unfortunately the C# Extension Methods are not that powerful as the Ruby's Monkey Patching and I am already far enough into the Ruby to recognize what power (and elegance) I am missing.
{
public static T LazyTryParse<T>(this T instance, object input)
{
Type type = typeof (T);
MemberInfo[] members = type.FindMembers(
MemberTypes.Method,
BindingFlags.Public | BindingFlags.Static,
(objMemberInfo, objSearch) => objMemberInfo.Name.Equals(objSearch.ToString()),
"TryParse"
);
foreach (MemberInfo info in members)
{
try
{
bool boolResult;
object[] paramArray=new[]{input, instance};
object objResult = ((MethodInfo) info).Invoke(instance, paramArray);
if (bool.TryParse(objResult.ToString(), out boolResult)) return (T)paramArray[1];
break;
}
catch {}
}
throw new ApplicationException(type+ " doesn't support TryParse");
}
}
Here is the test harness for the extension, which also shows the usage patterns (generic inference makes code look simpler):
[TestFixture]public class TryParseExtenderTest
{
[Test]
public void TestIntParsing()
{
string input = "230";
int result = 0;
result = result.LazyTryParse(input);
Assert.AreEqual(230, result);
}
[Test, ExpectedException(typeof(ApplicationException),
ExpectedMessage = "System.String doesn't support TryParse")]
public void TestStringParsing()
{
int input = 230;
string result = "";
result = result.LazyTryParse(input);
Assert.AreEqual("230", result);
}
[Test]
public void TestBooleanParsing()
{
string input = "true";
bool result = true;
result = result.LazyTryParse(input);
Assert.AreEqual(true, result);
}
[Test]
public void TestDateTimeParsing()
{
string input = new DateTime(2008, 12, 1).ToString();
DateTime result = DateTime.Now;
result = result.LazyTryParse(input);
Assert.AreEqual(new DateTime(2008, 12, 1), result);
}
}
2 comments:
Nice attempt Ruby wantatbe. Why don't you just complete the conversion and go completely Ruby all the way?
I am supporter of the Communist Programming Paradigm - strong static types, restrictive models, predictable inheritance, verbose assemblies.
Post a Comment