CScharpizzati

Nei mesi passati ho avuto l’opportunità di lavorare come software architect per un progetto basato su .NET e C#.

Da molti anni non bazzicavo in ambito Microsoft, e quindi è stata una utile palestra. Ho pensato di scrivere questo piccolo manuale per sviluppatori java con la ventura di dover diventare… C#-enabled.

Introduzione

C# è una evoluzione del C++ e quindi risulta leggermente più complesso e ricco di Java JDK 1.4.

C# è utilizzabile al posto del C++ all’interno dell’intera infrastruttura DCOM di Microsoft. Le ultime versioni di Java (JDK 1.5 e successive) hanno preso qualche ottima idea da C#, come le annotazioni.
Microsoft ha rubato Spring, e implementato un container IoC chiamato Unity, ben fatto a nostro parere.

C# nel day by day

Uno dei punti più deboli di C# è la mancanza del principio KISS tanto caro ai creator di Unix: è un linguaggio progettato con in mente l’ottimizzazione first of all, e questo è un suo limite endemico: l’opposto del principio di Occam. In informatica questo si traduce nella riduzione di costrutti e nello sviluppo di linguaggi “sintetici”.

All’opposto linguaggi come Perl, professando il mantra del “C’è più di un modo per farlo” hanno favorito una generale difficoltà di comprensione del codice redatto.

Mixin

C# presenta i mixin: la conseguenza è che ogni tanto le classi hanno dei “metodi in meno” se non importate la classe “friend” che aumenta il numero di metodi. Per es in Unity il metodo UnityContainer.LoadConfiguration è invocabile solo se includete anche la specifica classe che implementa tale metodo:

[csharp]using Microsoft.Practices.Unity.Configuration;
[…]
IUnityContainer uContainer = new UnityContainer();
uContainer = new UnityContainer().LoadConfiguration();[/csharp]

e naturalmente il compilatore non vi aiuta se dimenticate l’ “using” di cui sopra, e vi dice soltanto che il metodo non esiste!

Generics con covarianza ma solo per gli array

In Java i template sono stati introdotti ex post, e i progettisti hanno deciso di non seguire la strada del C++.

Per questa ragione in Java i template vengono gestiti solo a compile time, e disintegrati a runtime (type erasure). Questo fa perdere molto della loro utilità, compreso il fatto che il C++ prevedeva la possibilità di ottimizzare il codice a seconda del tipo (sigh).

List<Animal> e List<Cat> sono internamente sempre List<Object> con in più del codice che emette un errore a runtime se si cerca di mettere un Animal dentro un List<Cat>.
Ma è consentito mettere un Cat dentro una List<Animal>, se Cat è una sottoclasse di Animal.

In C# questo è consentito solo per gli array per cui questo è valido

[csharp]Animal[] animals = new Cat[5];
animals[0] = new Animal();[/csharp]

ma questo  no…

[csharp]List&lt;Animal&gt; animals=new List&lt;Cat&gt;(); // C# vi ferma qui
animals.Add(new Animal()); // a runtime animals è una List&lt;Cat&gt; ciccio…[/csharp]

Difatti se si ammettesse la linea (1) sarebbe possibile a runtime forzare un Animal dentro la lista di Gatti, generando un errore a runtime, come infatti proverebbe a fare la linea (2). Non tutti gli animali sono gatti, ma i gatti sono animali :)

Tecnicamente si dice che il C# impedice la covarianza per gli oggetti.

La conseguenza in Java è che i template perdono molto del loro fascino, ma si mantiene l’interoperabilità all’indietro con codice java compilato è al 100%

Type inference e lambda

Due feature molto interessanti di C# sono la type inference e le lambda function. La type inference prevede che sia il compilatore a scoprire quale è il tipo di un oggetto a compile time, evitando che voi lo dobbiate dichiarare:

[csharp]var a="Sono una stringa ciccio";
var b=System.ComponenteComSenzaSorgenti.cheTiFregaSaperlo();[/csharp]

Le lambda functions consentono le chiusure, che in Java sono possibili in modo complesso.
Le funzioni lambda poi si fondono con LINQ, un altro pezzo di ottimo codice del C# 3.0.

Data Access

Come si scrive una applicazione che deve accedere al DB? L’equivalente di JDBC+ORM in C# è ADO.NET, che è l’insieme di librerie di accesso e mapping degli oggetti sul db.
Esistono sostanzialmente due grandi strategie:

  • Linq2SQL
    Un sistema semplice che fa il mapping delle tabelle su degli oggetti. E’ semplice ed immediato, ma gestisce male le relazioni many-to-many (molti a molti) e quindi Microsoft lo sta progressivamente scoraggiando. Questo link dettaglia un “razionale” di come usarlo. Linq2SQL purtroppo al momento funziona solo su SQL Server, e questa è una forte limitazione.
  • Entity Framework, che però è piuttosto giovane (la prima versione è nata con .NET 3.5) e non ha ricevuto un caloroso benvenuto:

    Entity Framework was included with .NET Framework 3.5 Service Pack 1 and Visual Studio 2008 Service Pack 1, released on 11 August 2008. This version has been widely criticized, even attracting a ‘vote of no confidence’ signed by several hundred developers.

    Come si legge da WikiPedia.

Strumenti di sviluppo: non sempre pagando si trova il meglio…

Il Visual Studio è un ottimo ambiente, anche se le versioni gratuite (“Express”) non sono assolutamente da prendere in considerazione, perché eccessivamente limitate. Rispetto a Eclipse o NetBeans, Visual Studio è leggermente più comodo da usare. Un ottimo concorrente sarebbe stato JBuilder, se non fosse morto e sepolto

Microsoft è sicuramente una società XML-centrica, e fornisce tool di automazione dei vari componenti.
Anche il validatore dei CSS e dell’HTML è nettamente migliore di quelli che potete trovare in ambito Java, e vi consentono teoricamente di sviluppare codice. Creare gli stub per connettersi ad un web service anche Java è rapidissimo, ma i tol di refactoring e di terze parti ci paiono inferiori ad Eclipse. Eclipse insomma è un ambiente veramente aggressivo (e gratuito) ed è difficilissimo competere con lui.

Conclusioni

In buona sostanza i due linguaggi ad oggi sono equipollenti.
Java è molto ottimizzato nel multi threading, ma è fortemente incentrato su specifiche che vengono poi implementate da vendor di terze parti. Per cui Java è sì “gratis” ma gli application server sono costosissimi: le licenze di IBM WebSphere e Oracle WebLogic si pagano salatissime.

Di contro, se avete intenzione di sviluppare applicazioni basate su Microsoft Windows, Visual Studio è un all-inclusive pack molto ben organizzato.

Da questo punto di vista Java è molto debole: l’unica serie di widget che possono competere sono la SWT e la piattaforma Rich Client di Eclipse, ma genera eseguibili immensi e ben poco maneggevoli. Inoltre la copertura circa elementi grafici di terze parti è molto bassa.
Visual Studio è costosetto però: la versione base viene 1000 euro.
Sempre meno di una licenza per due CPU di IBM WebSphere, ma più di una versione di Tomcat con OpenEJB: intendiamo dire che in Java un buon servlet engine con un container EJB accettabile lo si può trovare anche gratis.

C# è una one-way street invece, difatti con C# non ci sono terze parti: il nocciolo del sistema è in mano a mamma Microsoft.
Lo stesso si può dire per Cocoa e iPhone: Apple fa e disfa le specifiche a sua convenienza, con la medesima politica.

I due approcci hanno vantaggi e svantaggi. Lo svantaggio dell’approccio di Java è che le specifiche sono sempre a due strati: c’è qualcuno che definisce una interfaccia complessa, per consentire a qualcun’altro di sviluppare un prodotto commerciale su di essa. C# invece ha come target platform il semplice PC, per cui è più snello sia mentalmente che tecnologicamente.

Riferimenti

http://onjava.com/pub/a/onjava/2001/10/04/csharp_java.html