开发者

How to format complex chained Linq statements for readibility?

开发者 https://www.devze.com 2023-02-13 20:05 出处:网络
I have some code like this: var effects = xElement.Elements ( \"Effects\" ).Elements ( \"Effect\" ).Select (

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 ();
0

精彩评论

暂无评论...
验证码 换一张
取 消