Reputation: 51927
I use the following code to validate income numbers from ajax calls:
public Tuple<bool, int> ValidateInt(string TheCandidateInt)
{
int TheInt = 0;
if (Int32.TryParse(TheCandidateInt, out TheInt))
{
return new Tuple<bool, int>(true, TheInt);
}
else
{
return new Tuple<bool, int>(false, 0);
}
}
public Tuple<bool, short> ValidateShort(string TheCandidateShort)
{
short TheShort = 0;
if (Int16.TryParse(TheCandidateShort, out TheShort))
{
return new Tuple<bool, short>(true, TheShort);
}
else
{
return new Tuple<bool, short>(false, 0);
}
}
I also have the same types of function for Byte
and Short
. As you can see, I pass in a string and the return is a Tuple where Item1 is a boolean and Item2 is the value.
Is there a way to change these 4 methods into 1 and somehow factor out the data type of the parsing?
Thanks.
Upvotes: 1
Views: 1070
Reputation: 22446
You can create a delegate that encapsulates the TryParse call and by that create a more general version of your validation methods. The following sample shows the outline:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TestTryParseDelegate
{
class Program
{
private delegate bool TryParseDelegate<T>(string candidate, out T result)
where T : struct;
private static Tuple<bool, T> Validate<T>(string candidate, TryParseDelegate<T> tryParseDel)
where T : struct
{
T result;
return Tuple.Create(tryParseDel(candidate, out result), result);
}
public static Tuple<bool, int> ValidateInt(string TheCandidateInt)
{
return Validate<int>(TheCandidateInt, int.TryParse);
}
public static void Main()
{
var result = ValidateInt("123");
Console.WriteLine(result);
}
}
}
I'd still suggest to encapsulate the general version in specialized methods as in your sample as the delegate is a implementation detail that you might not want to publish.
Upvotes: 0
Reputation: 4911
You can merge your methods into one using generics:
public static Tuple<bool, T> ValidateValue<T>(string input) where T : struct
{
T result = default(T);
try
{
result = (T)TypeDescriptor.GetConverter(typeof(T)).ConvertFromString(input);
}
catch
{
return new Tuple<bool, T>(false, result);
}
return new Tuple<bool, T>(true, result);
}
As to factoring out the data type of parsing, you will still have to specify it as generic parameter.
ValidateValue<byte>("255");
Upvotes: 2