Introduction
Recently, I came across a situation in which we wanted to convert string
value to ValueType
. So, I thought of writing some custom converter code that simplifies the conversion without calling Convert.ToXXX()
.
Background
There were two scenarios:
- Convert the
string
into Nullable types: If conversion succeeds, return value, else return null
. - Convert the
string
into Value
type: If conversion succeeds, return value, else return default value of that type.
Using the Code
Referring to the code, we solved the problem:
- Convert the
string
into Nullable types: If conversion succeeds, return value, else return null
. Achieved through: ConvertStringToNullableValueType<T>
- Convert the
string
into Value type: If conversion succeeds, return value, else return default value of that type. Achieved through: ConvertStringToValueType<T>
public static class Converter
{
public static T? ConvertStringToNullableValueType<T>(string str) where T : struct
{
try
{
if (!typeof (T).IsValueType)
throw new Exception();
var returnType = (T)Convert.ChangeType(str, typeof(T));
return returnType;
}
catch (Exception)
{
return null;
}
}
public static T ConvertStringToValueType<T>(string str) where T : struct
{
try
{
if (!typeof (T).IsValueType)
throw new Exception();
var returnType = (T)Convert.ChangeType(str, typeof(T));
return returnType;
}
catch (Exception)
{
return default(T);
}
}
}
Some basic test methods to check if the code works as expected:
[TestMethod]
public void ConvertStringToNullableValueTypeTest_OnPassingValidIntegerString_ShouldReturnInteger()
{
string str = "1000";
var intval= Converter.ConvertStringToNullableValueType<Int32>(str);
Assert.AreEqual(1000,intval);
}
[TestMethod]
public void ConvertStringToNullableValueTypeTest_OnPassingInvalidIntegerString_ShouldReturnNull()
{
string str = "1000A";
var intval = Converter.ConvertStringToNullableValueType<Int32>(str);
Assert.AreEqual(null, intval);
}
[TestMethod]
public void ConvertStringToValueTypeTest_OnPassingValidIntegerString_ShouldReturnInteger()
{
string str = "1000";
var intval = Converter.ConvertStringToValueType<Int32>(str);
Assert.AreEqual(1000, intval);
}
[TestMethod]
public void ConvertStringToValueTypeTest_OnPassingInvalidIntegerString_ShouldReturnZero()
{
string str = "1000A";
var intval = Converter.ConvertStringToValueType<Int32>(str);
Assert.AreEqual(0, intval);
}
Points of Interest
To simplify it further, I hooked up these methods of CustomConverter
class to String
class using concept of extension methods. To know more about extension methods, please refer to the MSDN link:
public static class StringExtension
{
public static T? ConvertStringToNullableValueType<T>(this string str) where T : struct
{
try
{
if (!typeof (T).IsValueType)
throw new Exception();
var returnType = (T) Convert.ChangeType(str, typeof (T));
return returnType;
}
catch (Exception)
{
return null;
}
}
public static T ConvertStringToValueType<T>(this string str) where T : struct
{
try
{
if (!typeof (T).IsValueType)
throw new Exception();
var returnType = (T) Convert.ChangeType(str, typeof (T));
return returnType;
}
catch (Exception)
{
return Activator.CreateInstance<T>();
}
}
}
And now, these methods can be invoked by using object of String
class!
[TestMethod]
public void ConvertStringToNullableValueType_OnPassingValidString_ShouldReturnValue()
{
var str = "1234";
var actual = str.ConvertStringToNullableValueType<Int32>();
Assert.AreEqual(1234, actual);
}
[TestMethod]
public void ConvertStringToNullableValueTypeTest_OnPassingInvalidString_ShouldReturnNull()
{
var str = "1234AA";
var actual = str.ConvertStringToNullableValueType<Int32>();
Assert.AreEqual(null, actual);
}
[TestMethod]
public void ConvertStringToValueType_OnPassingValidString_ShouldReturnValue()
{
string str = "1234";
var actual = str.ConvertStringToValueType<Int32>();
Assert.AreEqual(1234, actual);
}
[TestMethod]
public void onvertStringToValueTypeTest_OnPassingInvalidString_ShouldReturnZero()
{
string str = "1234ABCD";
var actual = str.ConvertStringToValueType<Int32>();
Assert.AreEqual(0, actual);
}
The source code contains the complete logic and few more sample tests!
Feel free to suggest some improvements. :)