views:

271

answers:

3

Code taken from here

I would like to hear some expert opinions on this extension method. I do plan to use it, but would like to hear about any known problems i may face.

Am i better of using on primative types TryParse methods?

public static T? TryParse<T>(this object obj) where T : struct
        {
            if (obj == null) return null;

            T? result = null;
            TypeConverter converter = TypeDescriptor.GetConverter(typeof(T));
            if (converter != null)
            {
                try
                {
                    string str = obj.ToString();
                    result = (T)converter.ConvertFromString(str);
                }
                catch (Exception ex)
                {
                    throw ex;
                }
            }

            return result;
        }
A: 

It uses reflection and thus may be slow, if performance is an issue.

Michael Damatov
+2  A: 

Generics are most useful when you want to vary the public contract of a method or class, and the internals of the method or class don't really care (or care much) about the type that varies.

Some examples:

List<T> is a collection you can put things in, and internally the class doesn't care (much) about what that type is.

T System.Linq.Enumerable.First<T>(IEnumerable<T> source) returns the first element out of a bunch of elements. This method doesn't need to know internally what type that is in order to get the job done.

By contrast, a parsing method must change its behavior based on the type of the result. In the supplied method, there is Strategy which pushes the behaviors out to other methods, but there is a runtime cost for that choice.

The alternative is to let the caller (who must know the Type or they couldn't call the generic method with it), pick the converter. This choice is able to be made at design time or compile time and so incurs 0 runtime cost.

Side Note: Please don't use the re-throw everything idiom. All it does is reset the call stack and you don't ever want to do that.

catch (Exception ex)
{
  throw ex;
}
David B
1 motivation for using this generic method is reduce calling client code vs using primative parsers. You are right that clients knows the runtime types but they but they must also handle exceptions. Also, can u link me on more info re resetiing stack trace? Thanks
Rethrowing link http://msdn.microsoft.com/en-us/library/ms182363(VS.80).aspx
David B
And, you could get the client to pass you the parser (as a Func<T, U> if nothing else), instead of the type - that would avoid the reflection.
David B
+4  A: 

The TryParse pattern is best following the standard pattern, which allows use with non-structs, too:

public static bool TryParse<T>(string s, out T value) {
    TypeConverter converter = TypeDescriptor.GetConverter(typeof(T));
    try {
        value = (T) converter.ConvertFromString(s);
        return true;
    } catch {
        value = default(T);
        return false;
    }
}

Note I've accepted a string here, because that is what me most commonly mean by TryParse; otherwise, Convert.ChangeType might be more appropriate.

I see no reason for this to be an extension method (as per this in the question's example), and certainly it is inadvisable to pollute object with too many extension methods.

Marc Gravell