我正在为项目构建XML反序列化器,我经常遇到这种类型的代码情况:
var myVariable = ParseNDecimal(xml.Element("myElement")) == null ?
0 : ParseNDecimal(xml.Element("myElement")).Value;
有没有更好的方法来撰写此声明?
编辑:也许我应该澄清一下我的例子,因为我有一个帮助方法将字符串解析为十进制。答案 0 :(得分:6)
您可以使用扩展方法:
public static T TryGetValue<T>( this XmlElement element ) {
if ( null == element ) return default(T);
return (T)element.Value;
}
...
...
var myVariable = xml.Element("myElement").TryGetValue<decimal>();
修改强>
“通用”解决方案:
static class Program {
static void Main() {
var xmlDecimal = new XElement( "decimal" );
xmlDecimal.Value = ( 123.456m ).ToString();
decimal valueOfDecimal_1 = xmlDecimal.ValueAs<decimal>( decimal.TryParse );
bool valueOfBool_1 = xmlDecimal.ValueAs<bool>( bool.TryParse );
var xmlBool = new XElement( "bool" );
xmlBool.Value = true.ToString();
decimal valueOfDecimal_2 = xmlBool.ValueAs<decimal>( decimal.TryParse );
bool valueOfBool_2 = xmlBool.ValueAs<bool>( bool.TryParse );
}
}
public static class StaticClass {
public delegate bool TryParseDelegate<T>( string text, out T value );
public static T ValueAs<T>( this XElement element, TryParseDelegate<T> parseDelegate ) {
return ValueAs<T>( element, parseDelegate, default( T ) );
}
public static T ValueAs<T>( this XElement element, TryParseDelegate<T> parseDelegate, T defaultValue ) {
if ( null == element ) { return defaultValue; }
T result;
bool ok = parseDelegate( element.Value, out result );
if ( ok ) { return result; }
return defaultValue;
}
}
答案 1 :(得分:5)
编辑:鉴于编辑过的问题,这更加简单。
它再次使用扩展方法,但现在不需要在方法中进行转换。
var myVariable = ParseNDecimal(xml.Element("myElement").ValueOrDefault("0"));
...
public static string ValueOrDefault(this XElement element,
string defaultValue)
{
return element != null ? element.Value : defaultValue;
}
如果您不喜欢使用字符串参数的方法,可以使用object
并调用ToString
,然后调用它:
var myVariable = ParseNDecimal(xml.Element("myElement").ValueOrDefault(0m));
但是,这对我来说有点不对劲。它假定解析将与ToString
格式化相反。
原始回答
语言中没有什么特别可以帮助你的。 (我不确定你是否有正确的代码 - 你不是指XAttribute
的东西?)我建议你写一个实用的方法:
var myVariable = xml.Element("myElement").ValueOrDefault(0m);
...
public static decimal ValueOrDefault(this XElement element,
decimal defaultValue)
{
return element != null ?(decimal) element.Value : defaultValue;
}
如果你调整问题中的代码,我会在这里为代码做同样的事情。我怀疑你确实意味着使用XAttribute
,这会导致泛型问题 - 我没有以通用方式编写上述内容,因为我相信你会想要调用{ {1}}“转换为十进制”运算符。通用转换不会这样做,因为它不知道在编译时你想要什么样的转换。但是,您可以为您感兴趣的所有结果类型重载上述方法。
答案 2 :(得分:1)
你可以用??操作员写得更干净一点,但我不确定你应该......
Element()
返回null,没有带有该名称的子元素,所以你可以在哪里使用?在默认元素中滑动。您需要在调用(decimal)
强制转换之前执行此操作:
var myVariable
= (decimal)(xml.Element("myElement") ?? new XElement("myElement", 0));
就像我说的那样,虽然这会起作用,但我不确定你应该这样做。 YMMV。