是否存在将对象转换为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)
可以抛出异常,所以您必须注意这一点。