Spis treści
1 Zmienne domniemane
2 Inicjalizatory obiektów
3 Inicjalizatory kolekcji
4 Inicjalizatory tablic
5 Typy anonimowe
6 Metody rozszerzające
7 Wyrażenie Lambda
8 LINQ
9 Podsumowanie
Nowości w C# 3.0
Najnowszą wersje języka C# można już używać w Visual Studio 2008. Microsoft wprowadził wiele nowych elementów do składni, które znacznie ułatwiają pisanie aplikacji. W artykule możesz znaleźć opis „po krótce” najważniejszych z nich.
Dotychczas chcąc zadeklarować zmienne lokalne używało się takiej konstrukcji:
A zatem należało jawnie podać typ zmiennej, w C# 3.0 można deklarować zmienne bez podania typu dzięki słowu kluczowemu var:
Kompilator sam rozpozna typy powyższych zmiennych, nie musimy się o to martwić. Taka deklaracja wymaga inicjalizatora, aby kompilator od razu mógł rozpoznać typ zmiennej (jak w powyższym przykładzie).
Jest to mechanizm, który pozwala podawać wartości pól i właściwości nowo tworzonego obiektu przy wywołaniu konstruktora. W kodzie poniżej istnieje deklaracja klasy CoOrdinate, która posiada dwa pola typu Int.
Inicjalizatory obiektów pozwalają na nadanie tworzonemu obiektowi wartości pół i właściwości, a robi się to w ten sposób:
Tym sposobem został utworzony obiekt klasy CoOrdinate, którego pola x i y będą miały wartość 0 (należy zwrócić uwagę, że klasa nie posiada deklaracji konstruktora, a udało nam się ustalić wartość jego pól, bez żmudnego pisania „this.Pole = …”).
Podobnie możemy uczynić z kolekcjami, i zamienić:
..na elegantszą wersję:
Konstrukcja podobna jak przy kolekcjach:
Myślę, że przykłady nie wymagają dodatkowego komentarza.
Ta enigmatyczna nazwa kryje pod sobą całkiem użyteczną rzecz w C#. Dzięki typom anonimowym możemy tworzyć obiekty klas, których deklaracja nie istnieje.
Powyższy kod pokazuje utworzenie nowego obiektu. Deklaracja klasy takiego obiektu w rzeczywistości może wyglądać tak:
Jednak tym już zajmuje się kompilator, dzięki temu programista może zaoszczędzić czas na deklarowaniu klasy i od razu zająć się obiektem jak poniżej:
Metody te pozwalają rozszerzyć funkcjonalność typów już istniejących. Mogą być one zadeklarowane tylko w klasach statycznych.
Przykład:
Metoda ta poszerza możliwości typu string o nową metodę ToInt32 (działanie metody myślę, że nie wymaga dodatkowego tłumaczenia). To co wyróżnia tę metodę od innych jest słowo kluczowe this w parametrze. Dzięki takiej metodzie będzie możliwe użycie poniższego kodu:
Tym sposobem rozszerzyliśmy klasę string bez jawnego dziedziczenia z niej, co wcześniej było niewykonalne.
Wyrażenie to (zapisywane jako ⇒ ) pozwala rozszerzyć możliwości delegacji. Poniższy przykład demonstruje użyje wyrażenia Lambda:
Jak widać wyrażenie to pozwala na jeszcze sprawniejsze użycie delegatów, na przykładzie metoda, na którą wskazuje delegat jest zadeklarowana „z miejsca”.
W pełnej nazwie : Language integrated query – jest to mechanizm, który pozwala na użycie znanych z języka SQL definicji do manipulowania danymi (DML - Data Manipulation Language) w samym kodzie C#. Innymi słowy technologia ta pozwala na użycie składni DML na obiektach w C# takich jak tablice, typy generyczne, bazy SQL czy też dane pobrane z XML.
Przykład:
Przykład powyżej pokazuje sposób użycia LINQ (używa przy okazji również innych elementów składni z C# 3.0). Z tablicy numbers wybieramy te elementy, których wartość jest mniejsza od 5. Jak widać wyrażenie takie jest o wiele bardziej elegantsze i logiczne, niż użycie pętli, warunków, przypisań. Zwróć uwagę, że wyrażenie SQL-podobne to nie łańcuch znaków string, co oznacza, że LINQ to nie jakaś klasa mająca wspólne korzenie z ADO.NET.
Rezultat wywołania programu:
Nie zawaham się powiedzieć, że LINQ to potężne narzędzie w rękach programisty, które znacznie ułatwia operacje na listach czy innych danych, które wprowadza nie tylko możliwości ale i elegancję do języka.
http://msdn2.microsoft.com/en-us/vcsharp/aa336746.aspx - pod tym linkiem znajdziecie 101 przykładów użycia LINQ w programach.
Jak widać język C# wraz z wersją 3.0 stał się jeszcze bardziej potężny wprowadzając coraz to nowe rozwiązania. Cóż.. pozostaje nam czekać na wersje 4.0 – kto wie co nam zgotują programiści z Redmond.
Przykłady pochodzą z oficjalnej specyfikacji języka C#, MSDN lub innych stron (gdzieniegdzie przerobione do potrzeb artykułu).
Zmienne domniemane
Dotychczas chcąc zadeklarować zmienne lokalne używało się takiej konstrukcji:
int i = 5; string s = "Hello"; double d = 1.0;
A zatem należało jawnie podać typ zmiennej, w C# 3.0 można deklarować zmienne bez podania typu dzięki słowu kluczowemu var:
var i = 5; var s = "Hello"; var d = 1.0;
Kompilator sam rozpozna typy powyższych zmiennych, nie musimy się o to martwić. Taka deklaracja wymaga inicjalizatora, aby kompilator od razu mógł rozpoznać typ zmiennej (jak w powyższym przykładzie).
Inicjalizatory obiektów
Jest to mechanizm, który pozwala podawać wartości pól i właściwości nowo tworzonego obiektu przy wywołaniu konstruktora. W kodzie poniżej istnieje deklaracja klasy CoOrdinate, która posiada dwa pola typu Int.
public class CoOrdinate { public int x ; public int y; }
Inicjalizatory obiektów pozwalają na nadanie tworzonemu obiektowi wartości pół i właściwości, a robi się to w ten sposób:
var myCoOrd = new CoOrdinate{ x = 0, y= 0} ;
Tym sposobem został utworzony obiekt klasy CoOrdinate, którego pola x i y będą miały wartość 0 (należy zwrócić uwagę, że klasa nie posiada deklaracji konstruktora, a udało nam się ustalić wartość jego pól, bez żmudnego pisania „this.Pole = …”).
Inicjalizatory kolekcji
Podobnie możemy uczynić z kolekcjami, i zamienić:
List<string> animals = new List<string>(); animals.Add("monkey"); animals.Add("donkey"); animals.Add("cow"); animals.Add("dog"); animals.Add("cat");
..na elegantszą wersję:
List<string> animals = new List<string> { "monkey", "donkey", "cow", "dog", "cat" } ;
Inicjalizatory tablic
Konstrukcja podobna jak przy kolekcjach:
var a = new[] { 1, 10, 100, 1000 }; // int[] var b = new[] { 1, 1.5, 2, 2.5 }; // double[] var c = new[] { "hello", null, "world” }; // string[]
Myślę, że przykłady nie wymagają dodatkowego komentarza.
Typy anonimowe
Ta enigmatyczna nazwa kryje pod sobą całkiem użyteczną rzecz w C#. Dzięki typom anonimowym możemy tworzyć obiekty klas, których deklaracja nie istnieje.
new {hair="black", skin="green", teethCount=64}
Powyższy kod pokazuje utworzenie nowego obiektu. Deklaracja klasy takiego obiektu w rzeczywistości może wyglądać tak:
class __Anonymous1 { private string _hair = "black"; private string _skin = "green"; private int _teeth = 64; public string hair {get { return _hair; } set { _hair = value; }} public string skin {get { return _skin; } set { _skin = value; }} public int teeth {get { return _teeth; } set { _teeth = value; }} }
Jednak tym już zajmuje się kompilator, dzięki temu programista może zaoszczędzić czas na deklarowaniu klasy i od razu zająć się obiektem jak poniżej:
var frankenstein = new {hair="black", skin="green", teethCount=64}
Metody rozszerzające
Metody te pozwalają rozszerzyć funkcjonalność typów już istniejących. Mogą być one zadeklarowane tylko w klasach statycznych.
Przykład:
public static int ToInt32(this string s) { return Convert.ToInt32(s) ; }
Metoda ta poszerza możliwości typu string o nową metodę ToInt32 (działanie metody myślę, że nie wymaga dodatkowego tłumaczenia). To co wyróżnia tę metodę od innych jest słowo kluczowe this w parametrze. Dzięki takiej metodzie będzie możliwe użycie poniższego kodu:
string s = "1"; int i = s.ToInt32();
Tym sposobem rozszerzyliśmy klasę string bez jawnego dziedziczenia z niej, co wcześniej było niewykonalne.
Wyrażenie Lambda
Wyrażenie to (zapisywane jako ⇒ ) pozwala rozszerzyć możliwości delegacji. Poniższy przykład demonstruje użyje wyrażenia Lambda:
class Program { delegate void DemoDelegate(); static void Main(string[] args) { DemoDelegate myDelegate = () => Console.WriteLine("Pierwsza metoda") ; myDelegate(); myDelegate = () => Console.WriteLine("Druga metoda") ; myDelegate(); } }
Jak widać wyrażenie to pozwala na jeszcze sprawniejsze użycie delegatów, na przykładzie metoda, na którą wskazuje delegat jest zadeklarowana „z miejsca”.
LINQ
W pełnej nazwie : Language integrated query – jest to mechanizm, który pozwala na użycie znanych z języka SQL definicji do manipulowania danymi (DML - Data Manipulation Language) w samym kodzie C#. Innymi słowy technologia ta pozwala na użycie składni DML na obiektach w C# takich jak tablice, typy generyczne, bazy SQL czy też dane pobrane z XML.
Przykład:
public void Linq1() { int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 }; var lowNums = from n in numbers where n < 5 select n; Console.WriteLine("Numbers < 5:"); foreach (var x in lowNums) { Console.WriteLine(x); } }
Przykład powyżej pokazuje sposób użycia LINQ (używa przy okazji również innych elementów składni z C# 3.0). Z tablicy numbers wybieramy te elementy, których wartość jest mniejsza od 5. Jak widać wyrażenie takie jest o wiele bardziej elegantsze i logiczne, niż użycie pętli, warunków, przypisań. Zwróć uwagę, że wyrażenie SQL-podobne to nie łańcuch znaków string, co oznacza, że LINQ to nie jakaś klasa mająca wspólne korzenie z ADO.NET.
Rezultat wywołania programu:
Numbers < 5: 4 1 3 2 0
Nie zawaham się powiedzieć, że LINQ to potężne narzędzie w rękach programisty, które znacznie ułatwia operacje na listach czy innych danych, które wprowadza nie tylko możliwości ale i elegancję do języka.
http://msdn2.microsoft.com/en-us/vcsharp/aa336746.aspx - pod tym linkiem znajdziecie 101 przykładów użycia LINQ w programach.
Podsumowanie
Jak widać język C# wraz z wersją 3.0 stał się jeszcze bardziej potężny wprowadzając coraz to nowe rozwiązania. Cóż.. pozostaje nam czekać na wersje 4.0 – kto wie co nam zgotują programiści z Redmond.
Przykłady pochodzą z oficjalnej specyfikacji języka C#, MSDN lub innych stron (gdzieniegdzie przerobione do potrzeb artykułu).
4 komentarze
WOow i to jest to co tygryski lubia najbardziej opłacało sie szarpać nad si :p
To jest ciekawy przykład:
public void Linq5() {
string[] digits = { "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine" };
var shortDigits = digits.Where((digit, index) => digit.Length < index);
Console.WriteLine("Short digits:");
foreach (var d in shortDigits) {
Console.WriteLine("The word {0} is shorter than its value.", d);
}
}
<quote>public string hair {get { return _hair; } set { _hair = value; }}</quote>
W nowym cs mozna zrobic bodaj:
public string hair {get; set; }
tyle że szkoda że nie ma wszystkiego z .NET na linuks