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
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; }
}
}
}