Jethro
Jethro

Reputation: 5916

Invalid cast from 'System.String' to 'System.TimeSpan'

I currently have a Generic method that reads an Value from the database based on a key and returns a specific type of that value.

    public T Get<T>(string key, T defaultValue)
    {
        var myparms = new List<SqlParameter>
                      {
                          new SqlParameter("@KEY", key),
                      };
        const string getPropertyQuery = "SELECT SPARM_VALUE FROM SYSPARAMS WHERE SPARM_KEY = @KEY;";

        var returnedValue = //Get value from Database

        if (returnedValue == null)
        {
            return defaultValue; //Value does not exists so return default.
        }

        return (T)Convert.ChangeType(returnedValue, typeof(T));
    }

But when I try and return a TimeSpan type I get the following exception. Invalid cast from 'System.String' to 'System.TimeSpan'.

After a bit of googling I found that the most common solution is to use the TimeSpan.Parse or TimeSpan.TryParse methods.

I also found TimeSpan Structure.

public struct TimeSpan : IComparable, IComparable, IEquatable, IFormattable

My question is why, why is TimeSpan not able to do this. Is it because it doesn't have the IConvertible interface? Any thoughts on this would be much appreciated.

Upvotes: 15

Views: 14396

Answers (3)

Oded
Oded

Reputation: 498904

There is no explicit cast/conversion defined between string and TimeSpan because most strings are not TimeSpans.

If the framework defined such a cast, would you also expect these to exist on DateTime and all other value types?

Upvotes: 1

Dean Chalk
Dean Chalk

Reputation: 20451

There isnt an implicit conversion between String and TimeSpan, you need to convert explicitly using Parse or TryParse

Upvotes: 1

Anton Gogolev
Anton Gogolev

Reputation: 115691

I don't think Convert.ChangeType is what you really want. Try TypeConverter.ConvertFrom:

var converter = TypeDescriptor.GetConverter(typeof(T));
return converter.CanConvertFrom(returnedValue) ? 
    (T)converter.ConvertFrom(returnedValue) :
    defaultValue;

Upvotes: 37

Related Questions