How to format complex chained Linq statements for readibility?
I have some code like this:
var effects = xElement.Elements ( "Effects" ).Elements ( "Effect" ).Select (
e => new Effect (
( EffectType ) Enum.Parse ( typeof ( EffectType ), ( string ) e.Elements ( "Type" ).FirstOrDefault ( ) ),
e.Elements ( "Options" ).Any ( )
? e.Elements ( "Options" ).Select ( o => ( object ) o.Elements ( "Option" ).Select ( n => n.Value ).First ( ) )
: null ) )
.ToList ( );
But currently this doesn't look as readable and I am not sure where I should add a new line开发者_C百科 and/or indent for readability.
Any suggestions I could use to make consistent, readable linq blocks?
Totally subjective question, don't even know why I am answering it but here's what looks more readable to me:
var effects = xElement
.Elements("Effects")
.Elements("Effect")
.Select(e =>
new Effect(
(EffectType)Enum.Parse(
typeof(EffectType),
(string)e.Elements("Type").FirstOrDefault()
),
e.Elements("Options").Any()
? e.Elements("Options").Select(
o => o.Elements("Option").Select(n => n.Value).First()
)
: null
)
)
.ToList();
or if you prefer the query syntax:
var effects =
from e in xElement.Elements("Effects").Elements("Effect")
let effectType =
(EffectType)Enum.Parse(
typeof(EffectType),
(string)e.Elements("Type").FirstOrDefault()
)
let options =
e.Elements("Options").Any()
? e.Elements("Options").Select(
o => o.Elements("Option").Select(n => n.Value).First()
)
: null
select new Effect(effectType, options);
I prefer small functions with clear names. Something like this:
public void Parse()
{
//XElement xElement = blah...
var elements = xElement.Elements("Effects").Elements("Effect");
var converted = elements.Select(ConvertToEffect);
}
private static Effect ConvertToEffect(XElement e)
{
var value = ConvertEnum((string) e.Elements("Type").FirstOrDefault());
var option = GetOption(e.Elements("Options"));
return new Effect(value, option);
}
private static EffectType ConvertEnum(string value)
{
return (EffectType)Enum.Parse(typeof(EffectType), value);
}
private static IEnumerable<object> GetOption(IEnumerable<XElement> e)
{
var any = e.Elements("Options").Any();
if (any)
{
return e.Elements("Options").Select(o => (object) o.Elements("Option").Select(n => n.Value).First());
}
return null;
}
Use query expression instead. I think it'll be more readable.
I think that I would format it something like this:
var effects =
xElement.Elements("Effects").Elements("Effect")
.Select (
e => new Effect(
(EffectType)Enum.Parse(
typeof(EffectType),
(string)e.Elements("Type").FirstOrDefault()
),
e.Elements("Options").Any() ?
e.Elements("Options")
.Select(o => (object)o.Elements("Option")
.Select(n => n.Value).First())
: null
)
)
.ToList ();
精彩评论