Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to use <T>.TryParse in a generic Method while T is either double or Int

Tags:

in one of my projects I'm using following two methods. 1. GetDoubleValue and 2. GetIntValue. GetDoubleValue uses double.TryParse to parameter str string and returns 0 if it fails while GetIntValue tries int.TryParse to parameter str string and returns 0 if it fails. What I want is to combine these two methods into one generic method that alongwith string str receives parameter T as well so that if I want to use GetDoubleValue Method I can use double for the parameter T and if I want to use GetIntValue Method I can use Int for the parameter T

public double GetDoubleValue(string str)
{
    double d;
    double.TryParse(str, out d);
    return d;
}
public int GetIntValue(string str)
{
    int i;
    int.TryParse(str, out i);
    return i;
}

Note: I have tried something like this;

private T GetDoubleOrIntValue<T>(string str) where T : struct 
{
    T t;
    t.TryParse(str, out t);
    return t;
}

EDIT

In my database I have more than 30 columns in differenct tables having numeric datatype. I want to insert 0 in each column if user does not type anything in the textbox i.e he leaves all or some of the textboxes empty. If I don't use the GetIntValue method I will have to use the method body more than 30 times. that is why I am doing this through method approach. I'm writing three of more than thirty examples for instance

cmd.Parameters.Add("@AddmissionFee", SqlDbType.Decimal).Value = GetIntValue(tbadmissionfee.Text);
cmd.Parameters.Add("@ComputerFee", SqlDbType.Decimal).Value = GetIntValue(tbcomputerfee.Text);
cmd.Parameters.Add("@NotesCharges", SqlDbType.Decimal).Value = GetDoubleValue(tbnotescharges.Text);

I want to combine the aforesaid two methods because today I'm having two methods like this which if combined will not give any better improvement in the programming but tomorrow I may have tens of methods like this that will better be combined into one generic method. e.g I may have GetInt32Value, GetShortValue etc. hope it is now cleared why I want this???

like image 298
kashif Avatar asked May 13 '12 19:05

kashif


People also ask

When you use the INT TryParse () method it is to convert a?

TryParse(String, Int32) Converts the string representation of a number to its 32-bit signed integer equivalent.

What method parameter type is used by TryParse method?

The type of this parameter is System. Char.

What is double TryParse?

Double TryParse(String, Double) converts the string representation of a number to its double-precision floating-point number equivalent. A return value indicates whether the conversion succeeded or failed.


3 Answers

I would consider writing an extension or static method:

delegate bool TryParse<T>(string str, out T value);  public static T GetValue<T>(this string str, TryParse<T> parseFunc) {     T val;     parseFunc(str, out val);     return val; } 

You then have to provide the TryParse implementation you want to use:

int i = "1234".GetValue<int>(int.TryParse); 

Be warned that this function silently returns a default value if the parse fails. You may want to return default(T) if the TryParse delegate returns false.

like image 193
Lee Avatar answered Sep 20 '22 11:09

Lee


I agree with Mark Byers. It's probably not a good idea to try making this method generic. A little code duplication won't hurt (as long as it really is only a little). The fact that you could use any struct with your generic version also doesn't make it look like a good idea to me.

If you really want to do this, you could try using reflection (like Minustar suggested), but that would be both ugly and slow.

Instead, you could use Convert.ChangeType():

private T GetValue<T>(string str) where T : struct 
{
    return (T)Convert.ChangeType(str, typeof(T));
}
like image 21
svick Avatar answered Sep 21 '22 11:09

svick


You could do something like this:

   public static T GetDoubleOrIntValue<T>(this string str) where T : IConvertible
{
    var thisType = default(T);
    var typeCode = thisType.GetTypeCode();
    if (typeCode == TypeCode.Double)
    {
        double d;
        double.TryParse(str, out d);
        return (T)Convert.ChangeType(d,typeCode) ;
    }
    else if (typeCode == TypeCode.Int32)
    {
        int i;
        int.TryParse(str, out i);
        return (T)Convert.ChangeType(i, typeCode);
    }
    return thisType;
}

Then when you call it:

string d = "1.1";
string i = "3";

double doubleValue = d.GetDoubleOrIntValue<double>();
int intValue = i.GetDoubleOrIntValue<int>();

But the whole thing seems kinda silly to me.

EDIT: Saw someone else using Convert.ChangeType...which provides for a generic return type.

like image 28
Eric Dahlvang Avatar answered Sep 21 '22 11:09

Eric Dahlvang