是否有单行方式将对象转换为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
。
执行此转换的suggested method是使用decimal.TryParse
,但是我不想为类中的每个小数属性创建一个临时变量(我的实际类中有大约7个属性,是小数,而不是3)。
decimal tmpvalue;
decimal? result = decimal.TryParse((string)value, out tmpvalue) ?
tmpvalue : (decimal?)null;
有没有办法可以在单行中向decimal?
投射潜在的空值?
我尝试了here发布的答案,但它似乎无法正常工作,并且还为null
提供row["ValueA"] as string
值,因为null
会返回{{1}}。
答案 0 :(得分:6)
您最好的选择是创建一个扩展方法。这是我使用的,虽然您可以调整它以返回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()
一样。
它不是一行,但它只是在使用它时的单个函数调用,并且它是非常可重用的。
编辑添加可空版本
答案 1 :(得分:4)
提供一个值,它读取为double,否则我认为它是一个字符串
好的,所以这会使问题变得复杂,因为有时你需要解析它,有时你却不需要解析它。
我们要做的第一件事就是检查它是否已经是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.
}
}
如果你知道它总是双倍的,你永远不会想要字符串值,那么它仍然更容易。在这种情况下,您需要将其转换为double,首先,因为它是真实类型,然后您可以轻松地将其转换为小数:
PropertyA = (decimal?)(row["ValueA"] as double?);
答案 2 :(得分:1)
decimal.TryParse
是要走的路。只需创建一个辅助方法并返回值。几乎和你提到的代码相同:
private decimal? convertToNullableDecimal(object value){
decimal tmpvalue;
return decimal.TryParse((string)value, out tmpvalue) ? tmpvalue : (decimal?)null;
}
<强>更新强>
这假设你需要一个可以为空的十进制数。否则,按照其他答案中的建议,使用内置方法:Convert.ToDecimal
答案 3 :(得分:0)
尝试类似
的内容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"])
};
答案 4 :(得分:0)
希望这有帮助
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
}
答案 5 :(得分:0)
您可以尝试Decimal.Parse方法。
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();
答案 6 :(得分:0)
Convert.ToDecimal(object)
几乎可以做你想要的。它将正确转换double值(不首先转换为字符串),还可以处理可转换为decimal的其他类型。它做得不好的一件事是空转换(或将String.Empty转换为null)。我会试着用扩展方法处理。
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)
可以抛出异常,因此您必须注意这一点。