BETA
Aby się zalogować, najpiew wybierz portal.
Aby się zarejestrować, najpiew wybierz portal.
Podaj słowa kluczowe
Słowa kluczowe muszą mieć co najmniej 3 sąsiadujące znaki alfanumeryczne
Pole zawiera niedozwolone znaki

Baza wiedzy











C# for non C programmers, czyli od Pascala do C#. Część 2. - Język C# - zagadnienia podstawowe. Składnia.

15-02-2005 00:55 | User 79314
Jest to drugi z serii artykułów wprowadzających w problematykę programowania w środowisku .NET w języku C#. Tym razem będziemy mówić o podstawowych zagadnieniach i składni języka C#.

Tekst, który właśnie czytasz jest drugim z serii artykułów wprowadzających w problematykę programowania w środowisku .NET w języku C#. Na początku bardzo przepraszam za tak duże opóźnienie z napisaniem tego artykułu w stosunku do pierwszej części. Spowodowane było awarią dysku twardego i utratą gotowego już tekstu. 

 Zacznijmy od napisania i omówienia prostej aplikacji konsolowej, której funkcjonalnością będzie wyświetlenie w oknie konsoli tekstu. W literaturze anglojęzycznej taki program określany jest mianem: „Hello, world!”, bo z reguły właśnie taki tekst wyświetla. Ja postanowiłem trzymać się języka polskiego. Wynik działania programu widzimy na rysunku poniżej.

Rzućmy okiem na kod.

[Kod C#]

using System;

class Class1
{
 static void Main()
 {
  Console.WriteLine("Witajcie wszyscy dookoła");
 }
}


 Co my tu mamy? Tak – powyższe 4 linijki kodu (nie licząc klamerek ;)) to jest cały kompilujący się i działający program. 

 Zatem po kolei. W pierwszej linijce widzimy dyrektywę using. Wskazuje ona na fakt, iż w naszym programie będziemy odwoływali się do przestrzeni nazw System. W tej przestrzeni nazw znajduje się użyta później klasa Console odpowiedzialna za obsługę okna konsoli oraz podstawowe operacje wejścia i wyjścia. Do przestrzeni nazw można też odwołać się jawnie, poprzez tzw. nazwę w pełni kwalifikowaną (fully-qualified name), np.

[Kod C#]

System.Console.WriteLine("Witajcie");

W takim przypadku nie trzeba używać dyrektywy using. Druga linia określa, że od tego momentu do klamerki zamykającej znajduje się definicja klasy o nazwie Class1. 

 OK. Zanim przejdę dalej wyjaśnię trochę tej fachowej chińszczyzny, której tutaj używam, wszak jest to artykuł nie tylko dla osób znających zagadnienia programowania obiektowego. 

 Co to jest obiekt? W programowaniu obiektem nazywamy zbiór danych wraz ze zbiorem operacji, które na tych danych można wykonać. 

 Co to jest klasa? Klasa to abstrakcyjny byt określający strukturę obiektu. Wyjaśnię to na przykładzie. Wyobraźmy sobie samochód. Niech to będzie Fiat 126p w kolorze złotym. Jest to konkretny obiekt. Możemy go zobaczyć, dotknąć, pojeździć nim. W zasadzie każdy samochód, który widzimy na ulicy jest obiektem. Spróbujmy sobie teraz wyobrazić samochód, któremu nie określamy żadnej marki, koloru, wielkości, ani żadnych innych parametrów. Wiemy że jest to samochód. To jest klasa. Każdy obiekt poruszający się po drodze (np. wspomniany wyżej złoty maluch) należy do tej klasy. Podobnie jest w programowaniu. Definiujemy klasę, a później tworzymy instancje obiektów tej klasy (tak się to fachowo mówi). Klasa składa się z właściwości oraz metod. Właściwości są to pola zawierające dane (np. liczba rzeczywista). Metody zaś są funkcjami operującymi na tych danych (np. pomnożenie przez 2). Dalsze szczegóły omówię przy okazji pojawiania się kolejnych przykładów kodu. 

 Co to jest przestrzeń nazw? Wyobraźmy sobie, że nad jednym projektem (jak na przykład portalem CodeGuru) pracuje kilkuset programistów. Bardzo łatwo może dojść do sytuacji, gdy dwóch lub więcej z nich nazwie tak samo klasę. W takiej sytuacji kompilator nie wiedziałby, o którą z nich przy danym wywołaniu chodzi. Przy tak dużej liczebności zespołu zapanowanie nad tym chaosem byłoby praktycznie niemożliwe. Stąd też używamy przestrzeni nazw (namespace) i przydzielamy każdemu programiście, lub grupie programistów zajmującej się określoną częścią projektu po jednej, np.

[Kod C#]

namespace CodeGuru.Modules.Articles

{}

odpowiedzialną za obsługę publikacji. 

 Nazwy muszą być unikalne w ramach jednej przestrzeni nazw, ale mogą się powtarzać w różnych. W przypadku niejednoznaczności przy odwołaniu do określonej nazwy podajemy też nazwę przestrzeni nazw, w której kompilator ma szukać danej klasy. Przestrzeń nazw deklarujemy poprzez użycie słowa kluczowego namespace i następującej po nim nazwie (jak to widać w przykładzie powyżej). Następnie pojawia się blok ograniczony klamerkami {}. Wszystko co zawiera się wewnątrz tego bloku należy do tej przestrzeni nazw. Do elementów przestrzeni nazw odwołujemy się na trzy sposoby:
1. Jeśli kod, który właśnie piszemy jest wewnątrz tej samej przestrzeni – nie ma potrzeby dokonywania żadnych specjalnych zabiegów.
2. Jeśli odwołanie jest z innej przestrzeni nazw, można to zrobić tak, jak widzieliśmy to na przykładzie pierwszego programu – poprzez dyrektywę using i nazwę przestrzeni.
3. Jednorazowe odwołanie można zapisać poprzez użycie nazwy w pełni kwalifikowanej:

[Kod C#]

namespace PrzykladowaAplikacja
{
 class Class1
 {
  static void Main()
  {
   System.Console.WriteLine("Witajcie wszyscy dookoła");
   System.Console.ReadLine();
  }
 }
}


 Użycie nazwy w pełni kwalifikowanej jest konieczne w przypadku gdy więcej niż jedna zadeklarowana przestrzeń nazw posiada klasy o tych samych nazwach.

 



 Wracając do naszego kodu, widzimy metodę Main(). Słowa static void poprzedzające jej nazwę to słowa kluczowe określające, że metoda jest statyczna, to znaczy, że można ją wywołać bez konieczności instancjonowania (tworzenia instancji) obiektu tej klasy (słowo static) oraz, że ta metoda nie zwraca żadnej wartości (słowo void). Funkcja Main() jest w języku C# tą, od której rozpoczyna się wywołanie programu. Zakończenie tej funkcji jest równoznaczne z zakończeniem wykonywania aplikacji. 

 UWAGA! Język C# rozróżnia wielkość liter. Nazwa metody Main() musi zawsze być pisana przez wielkie M z zachowaniem pozostałych liter małych. Metoda ta musi też zawsze być metodą statyczną.

 W naszym programie metoda Main() wykonuje tylko jedną operację: Console.WriteLine("Witajcie wszyscy dookoła"); Jest to wywołanie statycznej metody WriteLine() klasy Console. Metoda ta odpowiada za wypisanie swojego argumentu w oknie konsoli. W taki sposób napisana aplikacja znika od razu po pojawieniu się napisu. Aby komputer poczekał z zakończeniem programu do momentu naciśnięcia klawisza Enter, należy dodać jeszcze jedną linijkę: Console.ReadLine();. Funkcja ReadLine() wczytuje ze standardowego wejścia (czyli klawiatury) ciąg znaków zakończony znakiem końca linii. W naszym przypadku, będzie to po prostu oczekiwanie do naciśnięcia klawisza Enter.

 Przyjrzyjmy się bliżej klasie Console i zawartym w niej podstawowym metodom obsługi wejścia i wyjścia. Przed chwilą pokrótce opisałem działanie metod WriteLine() i ReadLine(). Obie te metody są przeciążone, to znaczy przyjmują różne listy parametrów. Dodatkowo chciałbym zaprezentować podobne metody Write() i Read(). 

 Klasa Console zapewnia odczyt ze standardowego strumienia wejściowego oraz zapis do standardowego strumienia wyjściowego oraz standardowego strumienia błędów. Domyślnie są nimi klawiatura – dla wejścia i ekran dla wyjścia oraz błędów. Jednakże każdy z tych strumieni można przekierować do innego urządzenia lub pliku, np. drukarki. W dalszej części artykułu będzie mowa o ekranie i klawiaturze, ale w rzeczywistości chodzi o strumienie wyjściowy i wejściowy.

 Metody Write() oraz WriteLine() powodują wyświetlenie określonego łańcucha znaków na monitorze. Różnica między nimi polega na tym, że druga z nich dodaje do tego łańcucha znaki końca linii i powrotu karetki, a pierwsza – nie. Metody te mogą przyjmować różne typy i ilości parametrów. Tak więc, aby wypisać na ekranie „56” możemy napisać:
Console.WriteLine(56); - tu argumentem jest liczba całkowita
lub
Console.WriteLine("56"); - gdzie argumentem jest łańcuch znaków.

 Funkcje te umożliwiają także formatowanie tekstu, np. wywołanie:
Console.WriteLine("Suma liczb: {0} i {1} wynosi: {2}", 43, 99, 43 + 99);
spowoduje wstawienie w miejsce znaczników {0}, {1} i {2} kolejnych, następujących po łańcuchu formatującym (tak nazywamy pierwszy, tekstowy parametr) parametrów, a więc wyświetlenie:
Suma liczb: 43 i 99 wynosi: 142

 Metody Read() oraz ReadLine() używane są do wczytywania danych z klawiatury. Metoda Read() powoduje wczytanie jednego znaku. Metoda ta zwraca liczbę całkowitą odpowiadającą pobranemu znakowi lub liczbę –1 w przypadku braku danych do pobrania. Metoda ReadLine() wczytuje całą linię, to znaczy ciąg znaków zakończony znakiem końca linii i zwraca pobrany łańcuch znaków. 

 Po uruchomieniu środowiska programistycznego Visual Studio .net i utworzeniu nowej aplikacji konsolowej widzimy trochę więcej kodu niż to, co wyżej zostało opisane, a mianowicie:

[Kod C#]

using System;

namespace ConsoleApplication2
{
 /// <summary>
 /// Summary description for Class1.
 /// </summary>
 class Class1
 {
  /// <summary>
  /// The main entry point for the application.
  /// </summary>
  [STAThread]
  static void Main(string[] args)
  {
   //
   // TODO: Add code to start application here
   //
  }
 }
}


 Kod ten jest bogatszy przede wszystkim o komentarze. W języku C# używamy 2 rodzajów komentarzy: komentarze kodu i dokumentacji. Te pierwsze oznaczamy znakami: // rozpoczynającymi komentarz trwający do końca bieżącej linii lub znakami: /* rozpoczynającymi komentarz trwający do pojawienia się znaków */. Taki komentarz może zawierać fragment jednej linii lub obszar składający się z wielu linii. Komentarze powinny być stosowane w celu opisu kodu i powinny być na tyle jasne, abyś ty sam po powrocie po dwóch latach do pracy nad kodem lub inny programista czytający twój kod był w stanie go zrozumieć.
Komentarze dokumentacji, oznaczane znakami /// tworzone są w formacie XML, co pozwala na automatyczne generowanie dokumentacji projektu jak również ułatwia pisanie innych części programu, gdyż te właśnie komentarze wyświetlane są przez tzw. IntelliSense jako podpowiedzi przy pisaniu kodu (jak na rysunku poniżej).


Bez użycia komentarzy

Z komentarzami

Komentarz do parametrów


 Jeszcze jedną ważną sprawą przy pisaniu programu jest obsługa sytuacji wyjątkowych. Wyobraźmy sobie, że podczas wykonywania programu nastąpiła jakaś nieoczekiwana sytuacja, np. dzielenie przez zero lub próba zapisu na dyskietkę, którą użytkownik właśnie wyjął ze stacji. W takiej sytuacji wykonanie naszej aplikacji po prostu zostanie zakończone przez system operacyjny. Jest na to jednak rada. Podczas tworzenia kodu programu należy zwrócić uwagę na miejsca, w których może dojść do takich nieoczekiwanych sytuacji i takie miejsca opakować w bloki try...catch...finally.

[Kod C#]

using System;

namespace ConsoleApplication2
{
 class Class1
 {
  static void Main()
  {
   
   int pierwsza = 123;
   int druga = 0;
   try
   {
    // Tu wykonujemy dzielenie przez zero:
    Console.WriteLine("Wartość: {0}", pierwsza / druga);
   }
   catch (Exception err)
   {
    Console.WriteLine("Wystąpił nieoczekiwany błąd: " + err.Message);
   }
   finally
   {
    Console.Read();
   }
  }
 }
}


 Powyższy kod powoduje wyświetlenie następującego komunikatu:


 Blok try{} zawiera miejsce narażone na wystąpienie błędu. Jeśli tak się zdarzy, wykonanie tego bloku jest przerywane i rozpoczyna się wykonywanie operacji w odpowiednim bloku catch(){}. Blok finally{} wykonywany jest bez względu na to, czy wystąpi błąd, czy też nie. Szczegółowy opis obsługi wyjątków znajdzie się w jednym z kolejnych artykułów.

 Wykonywanie metod, komentowanie kodu i obsługa błędów nie wystarczy jednak do napisania jakiejkolwiek funkcjonalnej aplikacji. Każdy program musi operować na danych. Dane w programie przechowywane są w zmiennych. Deklaracja zmiennej w języku C# wygląda następująco:

[Kod C#]

int pierwsza;

gdzie int to typ zmiennej (tu: liczba całkowita), zaś pierwsza – jej nazwa. Różne rodzaje zmiennych i typy danych opisane zostaną już w następnym (trzecim) artykule z tej serii. Mam nadzieję, że zdążę go opublikować przed awarią kolejnego dysku ;)

tagi: C#

Komentarze 2

andre.w
andre.w
0 pkt.
Nowicjusz
21-01-2010
oceń pozytywnie 0
prawdziwi twardziele nie robią backupów.
User 85016
User 85016
0 pkt.
Nowicjusz
21-01-2010
oceń pozytywnie 0
Lub glupcy ich nie robia !!
pkt.

Zaloguj się lub Zarejestruj się aby wykonać tę czynność.