Tuesday, May 29, 2007

REFLECTION in .NET

La possibilità di estendere un programma con dei moduli esterni che ne aumentino le funzionalità è resa possibile grazie ai potenti meccanismi della Riflessione: la capacità di introspezione messa a disposizione da .NET.

ESTENDERE UNA GERARCHIA DI CLASSI
Supponiamo di avere un programma che fa uso di una gerarchia di classi per gestire i propri dati. Supponiamo di voler dare a chiunque la possibilità di estendere la gerarchia con classi proprie. Il programma fungerà da "creatore" degli oggetti inseriti nella gerarchia delle classi.

STABILIRE LE INTERFACCE
Evidentemente le classi che dovranno essere utilizzate all'interno del programma dovranno avere un'interfaccia comune (in termini di metodi, campi e proprietà). E' necessario stabilire a priori gli elementi comuni per non dover modificare il programma successivamente. Esistono due possibili strade per stabilire gli elementi comuni alle classi:- definire una interfaccia all'interno di una libreria di classi (interfaccia che poi sarà implementata da chi vorrà realizzare una nuova classe nella gerarchia)- definire una classe radice che elenchi metodi, campi e proprietà. Tale classe può eventualmente essere una classe astratta

I PASSI DELLA IMPLEMENTAZIONE
1. Crere una Class Library (MasterLibrary) contenente la classe astratta o la definizione di interfaccia:
//CLASSE ASTRATTA
public abstract class TRoot
{
public int DatoInt;
public string DatoString;
public abstract int MetodoInt(int a);
public abstract string MetodoString(string s);
}
//INTERFACCIA
public interface IRoot
{
int MetodoInt1(int a);
string MetodoString1(string s);
}
2. Farne il Build per creare la dll. In questo modo abbiamo l'assembly contenente gli elementi essenziali per creare librerie di classi per estendere il programma
3. Nel programma che realizzeremo si dovranno utilizzare 2 metodi della System.Reflection (LoadFile e CreateInstance). Questi 2 metodi servono rispettivamente per recuperare l'assembly contenente le classi da noi definite e per creare l'istanza della classe presente all'interno dell'assembly stesso.
Il nome dell'assembly e della classe possono essere recuperati da un file di parametri usato dal programma.

ESTENDERE LA GERARCHIA DELLE CLASSI
1. Creare una Class Library includendo come Reference la MasterLibrary.dll;
2. Derivare ogni classe dalla TRoot (nel caso si usi la Classe Astratta) o dalla IRoot (nel caso si usi l'Interfaccia);
3. Implementare i metodi secondo la logica prevista;
4. Creare un file di configurazione contenente il nome dell'Assembly (.dll) completo di path ed il nome delle classi incluse al suo interno che vogliamo mettere a disposizione nel programma;

PER FINIRE
In pratica:
1. Nella MasterLibrary vengono definiti gli elementi (in termini di metodi e campi) che saranno implementati in tutte le classi che estenderanno la classe base
2. In tutte le estensioni si dovrà far riferimento alle classi definite nella MasterLibrary ereditando da quest'ultime
3. Nel programma si potrà far riferimento alle classi grazie ai metodi previsti a livello di Reflection, creando nuovi oggetti dalle classi definite all'esterno.

Sunday, May 06, 2007

Sui bravi programmatori

Riporto in inglese una frase estratta da un forum su VB estratto da Codeproject
"There are not bad languages, there are bad programmers, whatever language they use."
traduco: "Non ci sono linguaggi non buoni, ci sono programmatori non buoni, indipendentemente dal linguaggio che usano".

Vorrei riportare qui alcuni punti essenziali:
- VB ha permesso a molti (anche non professionisti) di sviluppare programmi
- VB ha indotto molti a credere che per scrivere un buon programma fosse sufficiente mettere alcuni controlli su una form senza avere alcun tipo di background scientifico per risolvere correttamente determinati problemi
- VB è stato ed è (VB.NET) un linguaggio come tanti altri che, se usato professionalmente può consentire di sviluppare ottimi programmi.

Per esperienza diretta:
- esistono linguaggi (Java per primo) che impongono dei paradigmi di programmazione che per essere compresi necessitano di una buona preparazione teorica
- qualunque linguaggio si usi la "strutturazione del codice" è fondamentale per una buona gestione dei progetti

Campi statici e variabili di classe

Ho letto questo blog e mi sono venuti alcuni dubbi che ho poi fugato facendo alcuni esempi.
Java ha sempre avuto i campi static, cioè le variabili globali a livello di classe. In Delphi questa caratteristica è stata introdotta (per rispettare .NET) dalla versione 8 (solo .NET) poi riportata nella versione per Win32.
Il dubbio che mi è sovvenuto è il seguente:
cosa succede nel caso che una classe derivi da un'altra che ha un campo static pubblico?

La risposta è la seguente:
il campo static (cioè la variabile di classe) è condivisa tra tutte le sottoclassi della classe che ha dichiarato quel campo come static. In pratica se ho queste classi:
T1 = class
class var a:integer;
...
end;
e
T2 = class(T1)
...
end;

T1.a e T2.a riferiscono la stessa variabile.

Se voglio differenziare T2.a da T1.a DEVO dichiararla nuovamente.

Questo è lo stesso comportamento di Java.

Come indicato nel post da me citato, la precedente possibilità era di quella di usare una variabile globale a livello di unit.

La situazione è ora molto più object oriented (anche per Delphi).