是否有单行方式将对象转换为小数



是否存在将对象转换为decimal?数据类型的单行方法?

我的代码看起来像这样:

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
}

然而,将对象强制转换为decimal?并不像我期望的那样工作,并且每次都返回null。

数据行是从Excel文件中读取的,因此每行中对象的数据类型要么是double(如果有值),要么是空string(如果为空)。

执行此强制转换的建议方法是使用decimal.TryParse,但是我不想为类上的每个小数属性创建一个临时变量(我的实际类中大约有7个属性是小数,而不是3个)。

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

是否有一种方法可以将潜在的空值转换为decimal?在单行中?

我尝试了答案张贴在这里,但它似乎没有工作,并给了我一个null值,因为row["ValueA"] as string返回null

最好的办法是创建一个扩展方法。这就是我使用的,尽管您可以将其调整为返回decimal?

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;
    }
}

你可以通过在任何对象上调用.ToDecimal()来使用它,就像你调用.ToString()一样。

它不是一行,但在使用它的地方它只是一个函数调用,并且它非常可重用。

编辑添加可空版本

如果存在一个值它就会读取为双精度类型,否则我认为它是一个字符串

好的,这使事情变得复杂,因为有时你需要解析它,有时你不需要。

我们要做的第一件事是检查它是否已经是double并对其进行强制转换,因为强制转换比解析便宜得多;解析是昂贵的。

如果这个逻辑是非平凡的,它属于它自己的方法:

public static deciaml? getDecimal(object rawValue)
{
    decimal finalValue;
    double? doubleValue = rawValue as double?;
    if(doubleValue.HasValue)
        return (decimal) doubleValue.Value;
    else if(decimal.TryParse(rawValue as string, out finalValue))
    {
        return finalValue;
    }
    else
    {
        return null;//could also throw an exception if you wanted.
    }
}

如果您知道它将始终是双精度类型,并且您永远不想要字符串值,那么它就更容易了。在这种情况下,首先需要将其强制转换为双精度类型,因为这是它的实际类型,然后可以轻松地将其转换为小数:

PropertyA = (decimal?)(row["ValueA"] as double?);

decimal.TryParse是可行的。只需创建一个助手方法并返回值。和你提到的代码差不多:

private decimal? convertToNullableDecimal(object value){
  decimal tmpvalue;
  return decimal.TryParse((string)value, out tmpvalue) ? tmpvalue : (decimal?)null;
}

假设您需要一个可为空的小数。否则按照其他答案的建议,使用内置方法:Convert.ToDecimal

试试

Func<object, decimal?> l_convert =
    (o) => decimal.TryParse((o ?? "").ToString(), out tmpvalue) ? tmpvalue : (decimal?)null;
var a = new ClassA()
{
     PropertyA = l_convert(row["ValueA"]),   
     PropertyB = l_convert(row["ValueB"]),
     PropertyC = l_convert(row["ValueC"])
};

希望对您有所帮助

decimal temp;
foreach(DataRow row in dt.Rows)
{
    var a = new ClassA()
    {
         PropertyA = Decimal.TryParse(row["ValueA"].ToString(), out temp) ? Convert.ToDecimal(row["ValueA"].ToString()) : (Decimal?) null,   
         ....
    };
    // Do something
}

您可以试试小数。解析方法。

public static decimal ToDecimal(this string value){
    try
    {
        return Decimal.Parse(value);
    }   
    catch (Exception)
    {
        //  catch FormatException, NullException
        return 0;
    }
}
//  use
PropertyA = row["ValueA"].ToString().ToDecimal();
PropertyB = row["ValueB"].ToString().ToDecimal();
PropertyC = row["ValueC"].ToString().ToDecimal();

Convert.ToDecimal(object)几乎是你想要的。它将正确地转换双精度值(不首先转换为字符串),并且还处理可以转换为十进制的其他类型。它做得不好的一件事是null转换(或String的转换)。从空到空)。我将尝试用一个扩展方法来处理这个问题。

public static class ObjectToDecimal
{
  public static decimal? ToNullableDecimal(this object obj)
  {
    if(obj == null) return null;
    if(obj is string && String.Empty.Equals(obj)) return null;
    return Convert.ToDecimal(obj);
  }
}

请记住,Convert.ToDecimal(object)可以抛出异常,所以您必须注意这一点。

相关内容

  • 没有找到相关文章

最新更新