V rámci přípravy na nějaké demo jsem si chvíli hrál s jazykovými novinkami v C# 3.0. Na první pohled se zdají možná trochu samoúčelné, ale vězte, že pro novou a velmi inovativní funkčnost označovanou jako LINQ jsou naprosto nezbytné a jsou jí také evidentně motivovány. O LINQ se pokusím něco napsat příští týden. Tak třeba se to někomu bude hodit, finální verze je již relativně za dveřmi. A ještě poznámka pro visualbasicáře - ve VB.NET jsou ekvivalentní novinky také, ale syntaxi po mne nechtějte Smile Více viz též na http://msdn.microsoft.com/msdnmag/issues/07/06/CSharp30/, ale i ledaskde jinde...

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Diagnostics;

 

namespace LanguageFeatures

{

    class Program

    {

        static void Main(string[] args)

        {

            List<string> jmena = new List<string> { "Karel", "Marie", "Josef", "Matous", "Magdalena", "Pepa" };

            List<double> cisla = new List<double> { 3.5, 13.9, -5.2, -15.2 };

            double maximum = 10;

 

            // Lambda Expressions umoznuji pouziti funkci jako parametru volani metod

            // varianta pro specificky typ

            List<int> poziceRetezcu1 = LambdaExpressions.IndexesWhere(jmena, s => s.Length<=5);

            // genericka varianta

            List<int> poziceCisel1 = LambdaExpressions.IndexesWhere<double>(cisla, c => Math.Abs(c)>maximum);

 

            // Extension Methods jsou staticke metody, ktere nabizi elegantni syntaxi pro pridavani metod k objektum

            // Zda se, jakoby narusovaly zapouzdreni, ale neni to pravda.

            // Jsou take do urcite miry nahradou za chybejici vicenasobnou dedicnost v .NET frameworku

            // varianta pro specificky typ

            List<int> poziceRetezcu2 = jmena.ObsoleteIndexesWhere(s => s.Length <= 5);

            // genericka varianta (vsimnete si, ze typ je uhadnuty)

            List<int> poziceRetezcu3 = jmena.IndexesWhere(s => s.Length <= 5);           

            List<int> poziceCisel2 = cisla.IndexesWhere(c => Math.Abs(c) > maximum);

 

            // Implicitni typ lokalni promenne

            // Typ je "uhadnuty" behem kompilace z prave strany vyrazu

            var str1 = "Hello world";

            var slova = str1.Split(char.Parse(" "));

            foreach (var s in slova) Console.WriteLine(s);

 

            // Anonymni typy v ramci lokalniho bloku kodu

            // Vypada to na prvni pohled trochu silene, ale je to velmi uzitecne pro LINQ funkce

            // Bez implicitnich typu lokalnich promennych by anonymni typy nebyly mozne

            var clovek = new { FullName = "Homer Simpson", Email = "homer@springfield.us" };

            Console.WriteLine(clovek.FullName + " - " + clovek.Email);

 

            // Inicializatory objektu

            // Umoznuji nastavit behem vytvareni objektu pole a vlastnosti bez nutnosti mit konstruktor

            Kniha k = new Kniha() { Autor = "Karel Capek", Titul = "Valka s mloky" };

        }

 

        // A na zaver - je mozne vytvorit definici vlastnosti bez nutnosti definovat pole na ulozeni (mozno dodefinovat pozdeji).

        // Nektere vlastnosti VS a .NET frameworku pozaduji vlastnosti misto poli,

        // takto je mozne je bezpracne definovat a pozdeji pripadne dotvorit.

        public string Foo { get; set; }

    }

 

    public class LambdaExpressions

    {

        // Varianta s presnou definici typu ve vyrazu (funkce nemusi byt staticka)

        public static List<int> IndexesWhere(List<string> items, Func<string, bool> predicate)

        {

            List<int> results = new List<int>();

            for (int i = 0; i < items.Count; i++ )

                if (predicate(items[ i ]))

                    results.Add(i);

            return results;

        }

 

        // Genericka varianta (funkce nemusi byt staticka)

        public static List<int> IndexesWhere<T>(List<T> items, Func<T, bool> predicate)

        {

            List<int> results = new List<int>();

            for (int i = 0; i < items.Count; i++)

                if (predicate(items[ i ]))

                    results.Add(i);

            return results;

        }

    }

 

    static class ExtensionMethods

    {

        // Varianta s presnou definici typu ve vyrazu v podstate postrada vedle genericke varianty smysl.

        // Rozsirujici metody se typicky delaji prave proto, aby byly genericke.

        public static List<int> ObsoleteIndexesWhere(this List<string> items, Func<string, bool> predicate)

        {

            List<int> results = new List<int>();

            for (int i = 0; i < items.Count; i++)

                if (predicate(items[ i ]))

                    results.Add(i);

            return results;

        }

 

        // Genericka varianta

        public static List<int> IndexesWhere<T>(this List<T> items, Func<T, bool> predicate)

        {

            List<int> results = new List<int>();

            for (int i = 0; i < items.Count; i++)

                if (predicate(items[ i ]))

                    results.Add(i);

            return results;

        }

    }

 

    public class Kniha

    {

        public string Autor;

 

        private string _titul;

        public string Titul

        {

            get { return _titul; }

            set { _titul = value; }

        }

    }

}