Obiective
- Familiarizarea cu mediul de lucru Visual Studio
- Reamintirea convențiilor de cod C#
- Extension Methods
- Delegates,
Func<T>,Action<T> - Exerciții — aplicații consolă C#
Mediul de lucru — Visual Studio
- Crearea unui proiect de tip Console Application (.NET)
- Structura unui proiect C# și fișierul
Program.cs - Rularea aplicației
Demo: creare proiect consolă și rulare exemplu simplu.
Convenții de cod C#
Spre deosebire de C, unde convențiile variază de la o bibliotecă la alta, C# este dezvoltat de Microsoft, iar convențiile oficiale reprezintă standardul. Familiarizarea cu ele de la început este esențială pentru un cod lizibil și consistent.
Extension Methods
Extension methods permit adăugarea de metode noi unor tipuri existente — inclusiv tipuri din .NET — fără a modifica tipul original și fără moștenire. LINQ se bazează masiv pe acest mecanism: Where(), Select(), OrderBy() sunt metode de extensie definite pe IEnumerable<T>.
Un extension method:
- este definit într-o clasă statică
- este la rândul lui static
- primul parametru indică tipul extins și este precedat de cuvântul cheie
this - se apelează ca o metodă de instanță obișnuită
Exemplu — numărare cuvinte într-un string:
public static class StringExtensions
{
public static int WordCount(this string str)
{
return str.Split(' ', StringSplitOptions.RemoveEmptyEntries).Length;
}
}
// Utilizare
var text = "ana are mere";
int count = text.WordCount(); // 3
Delegates
Un delegate este un tip care poate face referire la o metodă, permițând transmiterea unei funcții ca parametru sau stocarea ei într-o variabilă. Definește semnătura funcției (tipurile parametrilor și tipul returnat) și acceptă doar metode cu semnătură compatibilă.
Deși similar conceptual cu un function pointer, delegate-ul este complet type-safe.
În C# modern, delegații sunt utilizați cu expresii lambda în LINQ, mecanisme de callback, evenimente și programare asincronă (async/await).
Exemplu:
public delegate int Transformer(int x);
static int Square(int x)
{
return x * x;
}
Transformer t = Square;
int result = t(5); // 25
Func și Action
Func<T> și Action<T> sunt delegați generici predefiniți care elimină necesitatea definirii unor delegați personalizați.
| Tip | Descriere |
|---|---|
Action<T1, ...> |
Funcție care nu returnează valoare (void), primește parametri de tipurile specificate |
Func<T1, ..., TResult> |
Funcție care returnează o valoare de tip TResult |
Predicate<T> |
Echivalent cu Func<T, bool> — utilizat pentru condiții logice și filtrare |
Exemplu:
Action<string> log = s => Console.WriteLine(s);
log("Hello");
Func<int, bool> isEven = x => x % 2 == 0;
bool ok = isEven(10); // true
Exerciții
-
Creați o metodă de extensie pentru tipul
stringcare verifică dacă un text este palindrom. (1p) -
Scrieți o funcție care primește o listă de numere și o funcție
Func<int, bool>și returnează doar elementele care respectă condiția. (1p) -
Creați o metodă care primește un
stringși unPredicate<string>și returneazătruesaufalseîn funcție de evaluare. Testați cu o expresie lambda care verifică dacă lungimea textului este mai mare decât 5. (1p) -
Scrieți o funcție care primește o listă de numere întregi și o funcție
Func<int, int>, și returnează o listă nouă obținută prin aplicarea funcției asupra fiecărui element. (1p) -
Creați o metodă de extensie pentru
List<int>care returnează suma elementelor pare. (1p) -
Scrieți o metodă care primește o listă de string-uri și un
Action<string>, și aplică acțiunea pentru fiecare element. Testați cu o acțiune care afișează elementele la consolă. (1p) -
Implementați un mecanism simplu de notificare pentru utilizatori, folosind delegates și extension methods. Se consideră un tip de date
Usercu proprietățileNameșiAge. La înregistrarea unui utilizator (signup), mai multe componente independente trebuie notificate.- Definiți clasa
Userși utilizați un delegate multicast de tipAction<User>pentru notificare. Expuneți metodeleSubscribe()șiUnsubscribe(). (1p) - Definiți o clasă
SignupObserverscu cel puțin două metode statice observatori (ex: trimitere email și logare eveniment). (1p) - Atașați observatorii cu
Subscribe(), notificați la signup, eliminați un observator cuUnsubscribe()și demonstrați efectul. (1p) - Definiți clasa statică
UserExtensionscu o metodă de extensieDisplay()pentru afișarea informațiilor unui utilizator. (1p) - În
UserExtensions, implementațiNotifyAll()pentru notificarea tuturor utilizatorilor dintr-o colecțieList<User>. (1p) - Iterați lista de delegați folosind
GetInvocationList()și apelați fiecare handler separat. Ce avantaje oferă această abordare față de apelarea directă a delegate-ului multicast? (1p)
- Definiți clasa