Nowości w C# 3.0

Deti

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.

     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

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 komentarzy

tyle że szkoda że nie ma wszystkiego z .NET na linuks

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

public string hair {get { return _hair; } set { _hair = value; }}

W nowym cs mozna zrobic bodaj:

public string hair {get; set; }