IEnumerable.Dump()

Épp az egyik új tárgyunkhoz írok jegyzetet és példakódot LINQ to XML témában és felmerült, hogy kellene egy kényelmesen használható Dump metódus gyűjtemények elemeinek konzolra írásához.

Ha már úgyis C# 3.0 és .NET 3.5, akkor miért ne legyen extension method, legalább könnyű lesz újra felhasználni és talán kevesebbet is kell gépelni, amikor meg akarom hívni. Létrehoztam tehát egy névteret és egy statikus osztályt, benne pedig egy bővítő metódust:

    namespace LinqToXmlSample
    {
        public static class Extensions
        {
            /// <summary>
            /// Kiírja a konzolra egy gyűjtemény összes elemének értékét.
            /// </summary>
            /// <typeparam name="T">A gyűjtemény elemeinek típusa.</typeparam>
            /// <param name="collection">A feldolgozandó gyűjtemény.</param>
            public static void Dump<T>( this IEnumerable<T> collection )
            {
                foreach( T item in collection )
                {
                    Console.WriteLine( item );
                }

                Console.WriteLine( "nÖsszesen: {0} elem.n", collection.Count() );
            }
        }
    }

Egy statikus osztályban lévő statikus metódus attól lesz bővítő metódus, hogy a bővítendő típust adjuk meg első paramétereként, megelőzve őt a this kulcsszóval. Így a fenti Dump metódusom elérhető lesz minden IEnumerable<T> példányon.

Ettől kezdve vidáman tudtam ilyeneket írni:

    IEnumerable<XElement> acts = doc.Root.Elements( "ACT" );
    acts.Dump();

Ez már majdnem jó, csak az vele a gond, hogy az XElement egy ToString hívásnál nem csak a tartalmát, hanem a kacsacsőröket is beírja a válasz stringbe. Én pedig néha akarok kacsacsőröket, néha meg nem.

Ezért úgy döntöttem, hogy gyártok még egy Dump metódust, ami egy gyűjtemény elemeiből képzett tetszőleges értéket ki tud írni a konzolra. Ehhez felhasználtam a korábban már bemutatott Func delegate-et:

  /// <summary>
  /// Kiírja a konzolra egy gyűjtemény elemeiből tetszőlegesen képzett értékeket.
  /// </summary>
  /// <typeparam name="T">A gyűjtemény elemeinek típusa.</typeparam>
  /// <typeparam name="TResult">A gyűjtemény elemeiből képzett, a konzolra kiírandó értékek típusa.</typeparam>
  /// <param name="collection">A feldolgozandó gyűjtemény.</param>
  /// <param name="transformer">A gyűjtemény elemeit a kiírandó értékre alakító függvény.</param>
  public static void Dump<T, TResult>( this IEnumerable<T> collection, Func<T, TResult> transformer )
  {
      foreach( T item in collection )
      {
          Console.WriteLine( transformer( item ) );
      }
       Console.WriteLine( "nÖsszesen: {0} elem.n", collection.Count() );
  }

Ebben az a jó, hogy a transformer paraméter helyére tetszőleges függvényt írhatok, ami T bemeneti típusból TResult típust állít elő. Felhasználva a korábban már megértett lambda kifejezéseket, írhatok ilyeneket:

    IEnumerable<XElement> personas2 = doc.Root.Descendants( "PERSONA" );
    personas2.Dump( e => e.Value );            

Vagy persze akár komplexebbeket is:

    IEnumerable<XElement> acts = doc.Root.Elements( "ACT" );
    acts.Dump( e => e.Element( "TITLE" ).Value );

Az egészben talán az a legszebb, hogy egyetlen névtér hivatkozással ezek után bárhol el használhatom ezt a szintakszist, ami szerintem sokkal olvashatóbb, mintha mindenhol foreach és if hegyek lennének.

 

Advertisements

2 thoughts on “IEnumerable.Dump()

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s