3

I find the following scenario quite often: You have a string that you want to convert to an integer.

But first you must check:

        string sId = null;

        if (!string.IsNullOrEmpty(sId))
        {
            return int.Parse(sId);
        }
        else
        {
            return -1;
        }

But what i want is to be able to do this:

sId.As<int>(-1)

So what i can do is write an exension method as follows:

public static class ObjectExtensions
{
    public static T As<T>(this object instance, T defaultValue)
    {
        try
        {
            if (instance != null)
            {
                return (T)Convert.ChangeType(instance, typeof(T));
            }
        }
        catch
        {                
        }
        return defaultValue;
    }
}

My question is does anyone have a suggestion that this is a good approach?

Is there anything built into .NET 3.5 or up that is built in that can do this?

Andre
  • 3,717
  • 4
  • 25
  • 29
  • 1
    possible duplicate of http://stackoverflow.com/questions/390286/generic-parse-method-without-boxing – Baz1nga Oct 07 '11 at 11:30
  • You'd be better off using int.TryParse. – Joe White Oct 07 '11 at 11:47
  • [Related](http://stackoverflow.com/questions/856723/casting-value-to-t-in-a-generic-method), maybe helpful for you. FWIW I'd avoid adding an extension method to `object`, simply because it will pollute your intellisense absolutely everywhere... – Benjol Oct 07 '11 at 12:32

3 Answers3

2

Instead of catching the thrown exception, I would check if the type can be changed. In this question a CanChangeType method is described.

Community
  • 1
  • 1
thumbmunkeys
  • 20,606
  • 8
  • 62
  • 110
2

Couldn't you just use Int.TryParse instead?

string str = null;
int i;
bool result = Int32.TryParse(str, out i);
Jonas Elfström
  • 30,834
  • 6
  • 70
  • 106
  • the point is that he wants the users of his library to specify the target type; "int" was used as an example, but in practice it could be many other things as well. – Corey Kosak Oct 07 '11 at 11:55
  • Yes I could but there are 2 problems. First it doesnt seem to keep the default value if i initialise the integer to -1, and also theres the extra code to declare an int variable and then check the boolean. I wanted a nice elegant way to convert values that are stored in hashtables for instance (first check if null then try conversions). This will mostly be used for simple types. – Andre Oct 07 '11 at 11:56
1

I think it's OK if your program needs it but I'd like to make a few style suggestions:

  • call it Convert<T> rather than As<T>
  • let the defaultValue take a default
  • Consider not making it be an extension method. I know extension methods are great and all but I think there's something overly promiscuous about extension methods whose first argument is System.Object. The problem is you hit the autocomplete key in your IDE and you start finding a bunch of weird extension methods on every single object you use in your program. Converting isn't that common an operation, so I think I'd prefer MyUtil.Convert

So I'd slightly change your signature at least to:

public static class MyUtil {
  public static T Convert<T>(object instance, T defaultValue=default(T)) 

* EDIT *

I might also propose the alternative syntax

public static bool TryConvert<T>(object instance, out T result) {

* EDIT 2 *

And I might propose taking IConvertible rather than object, just to narrow the interface a little bit:

  public static T Convert<T>(IConvertible instance, T defaultValue=default(T)) {
     ...
  }
  public static bool TryConvert<T,U>(T instance, out U result) where T : IConvertible {
     ...
  }
Corey Kosak
  • 2,615
  • 17
  • 13