Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a single-line way of casting an object to a decimal?

Is there a single-line way of casting an object to a decimal? data type?

My code looks something like this:

foreach(DataRow row in dt.Rows)
{
    var a = new ClassA()
    {
         PropertyA = row["ValueA"] as decimal?,   
         PropertyB = row["ValueB"] as decimal?,
         PropertyC = row["ValueC"] as decimal?
    };

    // Do something

}

However casting an object to a decimal? doesn't work the way I expect it to, and returns null every time.

The data rows are read from an Excel file, so the data type of the object in each row is either a double if there is a value, or a null string if it's left blank.

The suggested method to perform this cast is to use decimal.TryParse, however I do not want to create a temp variable for every decimal property on the class (I have about 7 properties on my actual class that are decimals, not 3).

decimal tmpvalue;
decimal? result = decimal.TryParse((string)value, out tmpvalue) ?
                  tmpvalue : (decimal?)null;

Is there a way I can cast a potentially null value to a decimal? in a single line?

I tried the answer posted here, however it doesn't appear to be working and gives me a null value as well because row["ValueA"] as string returns null.

like image 633
Rachel Avatar asked Jan 02 '13 17:01

Rachel


1 Answers

Your best bet is to create an extension method. This is what I use, although you can tweak it to return a decimal? instead.

public static class ObjectExtensions
{
    public static decimal ToDecimal(this object number)
    {
        decimal value;
        if (number == null) return 0;
        if (decimal.TryParse(number.ToString().Replace("$", "").Replace(",", ""), out value))
            return value;
        else
            return 0;
    }
    public static decimal? ToNullableDecimal(this object number)
    {
        decimal value;
        if (number == null) return null;
        if (decimal.TryParse(number.ToString().Replace("$", "").Replace(",", ""), out value))
            return value;
        else
            return null;
    }

}

You would then use it by calling .ToDecimal() on any object, the same way you would call .ToString().

It's not one line, but it is only a single function call at the point where it's used, and it's very reusable.

Edited to add nullable version

like image 129
Bobson Avatar answered Oct 24 '22 20:10

Bobson