tpascale
tpascale

Reputation: 2576

c# Generics<T> / constraints question

Consider the following routine, which simplifies life for me by building in some default behaviors (e.g. no null values, don't parse "1,1,1" as a valid number):

public static Double CvtToDouble(Object O) 
  { 
    if (O == null) return (Double)0; 
    if (O == System.DBNull) return (Double)0; 
    if (O is string) return Double.Parse((String)O, 
                                     System.Globalization.NumberStyles.Float); 
    return (T)O;
}

This routine is then repeated for all the num types. I'd like to save on typing and typos by combining them all into

public static T CvtTo<T>(Object O) : where T : "is one of Int32, Int16 ..."

The usual "where T: struct" constraint isn't enough here, because of the "return (T)0" statement which is not valid for arbitrary value types. Seems like there ought to be some way to genericize this without bending over backward, but I don't see it. What am I missing ?

Upvotes: 3

Views: 168

Answers (4)

Pete Stens&#248;nes
Pete Stens&#248;nes

Reputation: 5695

You might want to consider a static class containing extension methods for each or your listed types to provide the CvtToDouble() extension method to each target type;

static class CvtToDoubleExtension
{
    static double CvtToDouble(this int arg)
    {
        return (double)arg;
    }

    static double CvtToDouble(this string arg)
    {
        return double.Parse(arg);
    }

    // Etc....
}

Its not as neat as your desired generic method, but its only 1 class and then the CvtToDouble method will bea available to all your desired types.

string example = "3.1412";
double value = example.CvtToDouble();

Upvotes: 1

Daniel Ives
Daniel Ives

Reputation: 727

You could try where T : IConvertible and change your last line to return Convert.ToDouble(O)? I'm pretty sure all the value types support that interface.

Upvotes: 3

sehe
sehe

Reputation: 394054

It isn't possible. See this excellent post:

https://stackoverflow.com/questions/138367/most-wanted-feature-for-c-4-0/138628#138628

Upvotes: 1

Lasse V. Karlsen
Lasse V. Karlsen

Reputation: 391734

You can't do it.

Generics in .NET is not templates, they are compiled once and thus has to be legal at compile time, not at invocation time.

Since there is no where T : number constraint, or no where T : op_add() constraint, you can't do this with just generics, you either need overloads or runtime checks to do this.

Upvotes: 6

Related Questions