14

I'm just learning about generics and have a question regarding method return values.

Say, I want a generic method in the sense that the required generic part of the method signature is only the return value. The method will always take one string as it's parameter but could return either a double or an int. Is this possible?

Effectively I want to take a string, parse the number contained within (which could be a double or an int) and then return that value.

Thanks.

1
  • 4
    This would be an inefficient use of generics (unless you're doing it solely to learn from). Since you need to know the type ahead of time, this particular task would be better served with Convert.ToDouble or Convert.ToInt32. The parse method would have no way of determining the type "automagically" just by looking at the string. You still need to know the type before the string is passed. Commented Jan 17, 2011 at 11:28

4 Answers 4

16

Something like this?

void Main()
{
    int iIntVal = ConvertTo<int>("10");
    double dDoubleVal = ConvertTo<double>("10.42");
}

public T ConvertTo<T>(string val) where T: struct
{
    return (T) System.Convert.ChangeType(val, Type.GetTypeCode(typeof(T)));
}
Sign up to request clarification or add additional context in comments.

2 Comments

How about var kvp = ConvertTo<KeyValuePair<int, List<string>>>("1, 2");? :)
@Benjol: Well, System.Convert.ChangeType should normally fail. There is no way to check if T type is convertible on compile time as there is no generic constraint for "simple" value types (the struct constraint will at least prevent from using reference types). So we'll leave the type validation to System.Convert.ChangeType during runtime.
12

You cannot return either a double or an int from a generic method without it also returning any other type.

I might, for example, have a Foo class and your generic parse method, without any constraint, will allow this call to be made:

Foo result = Parse<Foo>("111");

The best that you can do with numbers is constrain on your function by only allowing struct (value-types) to be used.

T Parse<T>(string value) where T : struct;

But this will allow all number types, plus any other value-type.

You can constrain by interface type, but there isn't an INumeric interface on double or int so you're kind of stuck.

The only thing that you can do is throw an exception if the wrong type is passed in - which generally isn't very satisfying.

Your best approach, in this case, is to abandon generics and use separately named methods.

double ParseDouble(string value);
int ParseInteger(string value);

But, of course, this won't help you learn generics. Sorry.

1 Comment

Thanks for the answer. I wanted to use generics as I thought it may be more efficient to simply have the one method. Obviously that is not the case and I will be best served continuing with the two methods that I currently use. Thanks.
9

Yes it's possible.

Example:

public T ParseValue<T>(String value) { 
    // ...
}

Comments

2

You could do something like ...

   public TResult Parse<TResult>(string parameter)
    {
     /* do stuff */
    }

And use it like ...

int result = Parse<int>("111");

And then it will depend on your implementation in the Parse method.

Hope it helps.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.