コガネブログ

平日更新を目標に Unity や C#、Visual Studio などのゲーム開発アレコレを書いていきます

【C#】XmlNodeList で LINQ の「Select」「Where」「First」「FirstOrDefault」を使用できるようにする拡張メソッド

ソースコード

using System;
using System.Collections.Generic;
using System.Xml;

public static class XmlExt
{
    public static IEnumerable<T> Select<T>
    ( 
        this XmlNodeList self, 
        Func<XmlNode, T> selector 
    )
    {
        foreach ( XmlNode n in self )
        {
            yield return selector( n );
        }
    }
    
    public static IEnumerable<T> Select<T>
    ( 
        this XmlNodeList      self, 
        Func<XmlNode, int, T> selector 
    )
    {
        var index = 0;
        foreach ( XmlNode n in self )
        {
            yield return selector( n, index++ );
        }
    }
    
    public static IEnumerable<XmlNode> Where
    ( 
        this XmlNodeList    self, 
        Func<XmlNode, bool> predicate 
    )
    {
        foreach ( XmlNode n in self )
        {
            if ( predicate( n ) )
            {
                yield return n;
            }
        }
    }
        
    public static IEnumerable<XmlNode> Where
    ( 
        this XmlNodeList         self, 
        Func<XmlNode, int, bool> predicate 
    )
    {
        var index = 0;
        foreach ( XmlNode n in self )
        {
            if ( predicate( n, index++ ) )
            {
                yield return n;
            }
        }
    }

    public static XmlNode First( this XmlNodeList self )
    {
        return self[ 0 ];
    }
        
    public static XmlNode First
    ( 
        this XmlNodeList    self, 
        Func<XmlNode, bool> predicate 
    )
    {
        foreach ( XmlNode n in self )
        {
            if ( predicate( n ) )
            {
                return n;
            }
        }
        throw new InvalidOperationException();
    }
    
    public static XmlNode FirstOrDefault( this XmlNodeList self )
    {
        return 0 < self.Count ? self[ 0 ] : null;
    }
        
    public static XmlNode FirstOrDefault
    ( 
        this XmlNodeList    self, 
        Func<XmlNode, bool> predicate 
    )
    {
        foreach ( XmlNode n in self )
        {
            if ( predicate( n ) )
            {
                return n;
            }
        }
        return null;
    }
}