Inserito da: msolcia | Novembre 25, 2008

“Overloading di WebMethod?”, “No grazie!”

Oggi stavo estendendo il web service della nostra applicazione aggiungendo due nuovi web methods. I due web methods in questioni fanno la stessa cosa di altri due web methods già presenti ma a differenza di essi hanno un parametro in più.

In pratica ho:

[WebMethod]public DataSet ReadData(string applicationName, DataSet dataSet) {…}

[WebMethod]public bool WriteData(string applicationName, DataSet dataSet){…}

Quindi mi sono detto: “facile, uso l’overloading in C#, inserisco i due nuovi metodi chiamandoli come i vecchi e cambiando solo il numero dei parametri; poi il web server funzionerà allo stesso modo”. Et voila

[WebMethod]public DataSet ReadData(string applicationName, DataSet dataSet) {…}

[WebMethod]public bool WriteData(string applicationName, DataSet dataSet){…}

[WebMethod]public DataSet ReadData(string moduleName, string applicationName, DataSet dataSet) {…}

[WebMethod]public bool WriteData(string moduleName, string applicationName, DataSet dataSet){…}

Sbagliato!!

Quando da Visual Studio cerco di aggiornare la signature del Web Service per un mio client di test, questo mi risponde:

“Both ReadData(string applicationName, DataSet dataSet) and public DataSet ReadData(string moduleName, string applicationName, DataSet dataSet) use the same name ‘ReadData"’. Use the Messa” <— il bello che qui il messaggio si tronca!!!

Va beh una rapida ricerca nel web e scopro che i WebMethods non possono avere lo stesso nome. [In realtà scopro ora che per avere l’errore completo basta fare browse su service.asmx]

Quindi lato C# posso naturalmente usare l’overloading poi però in fase di pubblicazione devo differenziare i metodi attraverso la proprietà “MessageName” dell’attributo WebMethod.

Cambio dunque il codice sopra in:

[WebMethod]public DataSet ReadData(string applicationName, DataSet dataSet) {…}

[WebMethod]public bool WriteData(string applicationName, DataSet dataSet){…}

[WebMethod (MessageName=”ReadDataForModule”)]public DataSet ReadData(string moduleName, string applicationName, DataSet dataSet) {…}

[WebMethod (MessageName=”WriteDataForModule”)]]public bool WriteData(string moduleName, string applicationName, DataSet dataSet){…}

E riprovo a fare l’update del Web Service dal mio client. Stavolta l’errore è il seguente:

Server Error in ‘/WebServices’ Application.

Service ‘Service’ does not conform to WS-I Basic Profile v1.1. Please examine each of the normative statement violations below. To turn off conformance check set the ConformanceClaims property on corresponding WebServiceBinding attribute to WsiClaims.None.
R2304: Operation name overloading in a wsdl:portType is disallowed by the Profile. A wsdl:portType in a DESCRIPTION MUST have operations with distinct values for their name attributes. Note that this requirement applies only to the wsdl:operations within a given wsdl:portType. A wsdl:portType may have wsdl:operations with names that are the same as those found in other wsdl:portTypes.
-  Operation ‘ReadData’ on portType ‘ServiceSoap’ from namespace ‘http://txt.it/webservices/’.
-  Operation ‘WriteData’ on portType ‘ServiceSoap’ from namespace ‘http://txt.it/webservices/’.
To make service conformant please make sure that all web methods belonging to the same binding have unique names.

 

Documentandomi un po’ in rete trovo che le mie modifiche fanno si che il web service non è più conforme ad una serie di regole guida definite per garantire l’interoperabilità (le guidelines sono qui) . Nello specifico la R2304 dice:

“R2304 A wsdl:portType in a DESCRIPTION MUST have operations with distinct values for their name attributes. Note that this requirement applies only to the wsdl:operations within a given wsdl:portType. A wsdl:portType may have wsdl:operations with names that are the same as those found in other wsdl:portTypes.”

In pratica anche se ho usato la proprietà MessageName, si sta lamentando del fatto che ho metodi con lo stesso nome.

Penso che sia possibile disabilitare il check di queste guidelines ma scelgo la strada più semplice e tolgo l’overloading.

[WebMethod]public DataSet ReadData(string applicationName, DataSet dataSet) {…}

[WebMethod]public bool WriteData(string applicationName, DataSet dataSet){…}

[WebMethod]public DataSet ReadDataForModule(string moduleName, string applicationName, DataSet dataSet) {…}

[WebMethod]public bool WriteDataForModule(string moduleName, string applicationName, DataSet dataSet){…}

Dunque overloading di web method? No grazie.

Inserito da: msolcia | Ottobre 22, 2008

Excel: Filtri avanzati

Tra i tanti libri che sto leggendo (ho questa mania di leggerli in parallelo e di finirne così 1-2 all’anno :-( ) c’è “Excel 2007 Data Analysis for Dummies”. Solitamente preferisco libri per utenti esperti (bible, step-by-step, ecc.) ma trovo che la collana “For Dummies” abbia il pregio di evitare di trattare i minimi dettagli ed andare subito al sodo, il che è utile se si vuole diventare subito operativi su un applicativo/tecnologia, non certo se si deve sostenere una certificazione.

Excel è veramente un prodotto sterminato, una cosa interessante che non sapevo è la possibilità di definire dei filtri avanzati.

A) Data una tabella come la seguente

Negozio Prodotto Quantità Prezzo
Esselunga Latte 12 2
Auchan The 10 3
Tesco Pollo 10 5
Tesco Burro 5 3
Tesco Pomodori 20 1

 

B) Supponiamo di voler filtrare le righe che hanno una quantità maggiore di 5 e un prezzo minore di 3.

Chiaramente con Excel 2007 si può fare avvalendosi del menu autofilter in ciascuna colonna oppure usando i filtri avanzati. Per usare questi ultimi:

1) Bisogna mettere da qualche parte nello sheet una riga con i nomi delle colonne su cui si vuole applicare un filtro e sotto questa riga un’altra con i relativi predicati di filtro. In questo caso avremo

Quantity Prezzo
>5 <3

 

2) Porsi nella tabella da filtrare,

3) Scegliere il tab “Data”, identificare il ribbon group “Sort & Filter” e premere su Advanced, comparirà la finistra seguente:

clip_image001

 

4) Assicurarsi che “List range” contenga i dati che si vogliono filtrare, “Criteria range” contenga il range di celle definito al punto 1) (colonne + condizioni) e si preme OK.

5) Il risultato sarà la tabella filtrata. E’ possibile farsì che la tabella venga filtrata sul posto “in-place” oppure che i valori che soddisfano il filtro vengano copiati in un altro range di celle.

Chissà se userò mai stai feature?

Inserito da: msolcia | Settembre 2, 2008

Constructing Classes – parte 1 (Esame 70-536)

Avevo accantonato un po’ questa avventura negli ultimi tempi per vari motivi: primo fra tutti la mancanza di tempo. Ora siamo in una situazione di ripartenza post-vacanze dunque ho qualche attimo in più per leggere/scrivere/studiare. Per cui riprendo dal post precedente sull’argomento esame 70-536.

La lezione 3 del libro "MCTS Self-Paced Training Kit (Exam 70-536): Microsoft .NET Framework 2.0 – Application Development Foundation" passa in rassegna l’ereditarietà, le interfacce, le partial class, i tipi generici, gli eventi, gli attributi e il type forwarding. Non oso pensare che qualcuno voglia sostenere l’esame 70-536 senza aver mai visto queste cose prima, infatti ritengo che questa lezione sia una semplice “rispolverata”, non certo sufficiente per chi è completamente a digiuno di questi concetti. Per costoro consiglio vivamente di documentarsi presso altre fonti, ad esempio, per chi ha deciso di usare C# come linguaggio, il libro “Wrox – Professional C#, 3Rd Edition” o l’ottimo reference “C# Language Specification” che si trova qui.

Per gli altri invece farò un breve ripasso, soffermandomi su Partial Class, Event e Type Forwarding che, sinceramente conosco un po’ meno:

Ereditarietà. L’ereditarietà consente di definire una nuova classe partendo da una classe già esistente. La classe derivata eredita attributi ed operazioni della classe base e può estenderli.

Dalle relazioni tra classe base e derivate scaturisce una modalità consistente di uso delle classi (pensiamo se le migliaia di classi .NET fossero tutte scorrelate e con modalità di uso diverse!): una Bitmap che deriva da una Image può essere usata nello stesso modo in cui si usa quest’ultima, con la possibilità però di poter usare funzionalità specifiche della Bitmap non presenti in Image.

Altra importante caratteristiche è che una classe derivata è una sorta di sottotipo del tipo base, dunque essa può essere usata in tutti i contesti in cui può essere usata la classe base. Classi derivate da una singola classe base possono essere usate in modo intercambiabile. Esempio il metodo Graphics.DrawRectangle richiede un oggetto di tipo Brush, ad esso possono essere passati oggetti di classi derivate da Brush, ad esempio: HatchBrush, LinearGradientBrush, ecc.

Interfaccia. L’interfaccia definisce un insieme di operazioni che devono essere rese disponibili da tutte le classe che aderiscono a (implementano/ereditano) questa interfaccia. E’ un vero e proprio contratto che aggiunge, come l’ereditarietà, consistenza al modo di usare le classi: l’utilizzatore di una classe che eredità da una certa interfaccia è sicuro di poter trovare (e quindi usare) le operazioni descritte nell’interfaccia.

Ecco alcune interfacce del framework .NET:

IComparable: una classe che implementa questa interfaccia può essere confrontata con un’altra classe che la implementa. E’ quindi importante nelle operazioni di ordinamento.

IDisposable: questa interfaccia regolamenta dei metodi che permettono di liberare risorse critiche usate dalla classe che implementa l’interfaccia.

IConvertible: mette a disposizione della classe che la implementa una serie di metodi per convertirsi in Boolean, Byte, Double, String

ICloneable: mette a disposizione i metodi per clonare un oggetto.

IEquatable: simile alla IComparable, consente di eguagliare due oggetti.

IFormattable: mette a disposizione metodi per formattazioni avanzate

E’ naturalmente possibile creare delle proprie interfacce:

interface IMiaInterfaccia
{
    bool FaiQuesto();
    string FaiQuello( get; set; );
} 

Partial class. Le partial class sono una novità del framework .NET 2.0

in pratica è la possibilità di spezzare in diversi file la definizione di una classe. Il vantaggio è quello di mettere in un file le parti più importanti lasciando in un altro file i dettagli non significativi per un programmatore (ad esempio le parti generate automaticamente da qualche wizard o designer).

Generics. Anche i generics sono una novità del framework .NET 2.0. Un tipo generico è un tipo in cui alcune caratteristiche (i tipi dei membri) sono parametrizzate e dunque non decise all’atto della definizione del tipo, ma all’atto dell’utilizzo dello stesso. Questo consente di poter utilizzare il tipo generico in diversi contesti, semplicemente modificando il valore dei parametri. Ad esempio si può costruire una classe Lista parametrica sul tipo di oggetti contenuti. In questo modo la Lista potrebbe contenere string, int o qualsiasi altro tipo.

In realtà il framwork .NET contiene molti tipi generici, soprattutto riguardanti collezioni di oggetti, essi sono contenuti nel namespace System.Collections.Generic.

Qualcuno potrebbe dire “si va bene, belli i generic, ma si può farne a meno: poichè tutti gli oggetti derivano da System.Object, si può  fare un down-cast a System.Object, ed usare quest’ultimo ad esempio nelle collection”, tutto vero ma i generics hanno i seguenti vantaggi:

- Type safe: l’uso del System.Object espone a possibili errori in run-time. Infatti una volta che si vuole usare l’oggetto bisogna effettuare un cast da System.Object al suo tipo originale. L’operazione di cast non è controllata a compile-time e dunque un’errata “manovra” può causare un exception a run-time (es. fare un cast ad int di un oggetto originariamente di tipo string). Con i generics questo non è possibile in quanto la correttezza viene controllata dal compilatore stesso.

- Performance: il cast da/vero System.Object richiede operazioni di boxing/unboxing (vedremo nel proseguo cosa significa altrimenti il post mi diviene kilometrico!). Queste operazioni rallentano grandemente l’esecuzione del programma. L’uso dei generics invece non richiede questo tipo di conversioni ed è quindi più performante.

Facciamo un parallelo tra uso dei generics e uso di System.Object:

 </p>
// Uso della classe OggettoOggetto myObject = new Oggetto (3, “Prova”); Console.WriteLine(“{0} {1}”, (int) myObject._a, (string) myObject._b); // Uso della classe GenericaGenerica<int string ,> myGeneric = new Generica<int string ,>(a, b); Console.WriteLine(“{0} {1}”, myGeneric._a, myGeneric._b); 

<p>

l’esempio sopra produce lo stesso output per entrambe le classi anche se la versione per generic è molto più performante (naturalmente per accorgersi di questa differenza bisognerebbe allocare svariate classi). da notare inoltre che se cambiassi il cast della versione object da (string) a (int) avrei un errore a run-time, mentre se lo facessi nella versione generics il compilatore mi avviserebbe a compile-time.

nota importante: nella definizione della classe generica il compilatore assume che i parametri (t e u nell’esempio) siano di tipo object. cioè le nostre classi generiche sono limitate dalle potenzialità di object, questo perchè a priori il compilatore non sa quali tipi verranno poi usati dal codice che usa la classe generica. e’ come dire che il compilatore per accontentare tutti prende il minimo comun denominatore: la classe object appunto.

per consentire che la classe generica abbia potenzialità “maggiori” di una semplice classe object si può istruire il compilatore dichiarando che i tipi parametrici avranno determinate caratteristiche. questo è possibile tramite i constraints che sono di quattro tipi:

- interface: la classe può usare solo tipi parametrici che implementano specifiche interfacce,

- base class: la classe può usare solo tipi parametrici che discendono da una specifica classe,

- constructor: la classe può usare solo tipi parametrici

- reference o value types: la classe può usare solo tipi parametrici che siano reference o value types.

per definire che una classe generics debba obbedire ad un dato constraint è sufficiente porre la clausola "where” dopo il nome della classe. esempio:

 </p>
class generica <t>where t : icomparable { public t t1; public t t2; public compgen(t _t1, t _t2) { t1 = _t1; t2 = _t2; } public t max() { if (t2.compareto(t1) &lt; 0) return t1; else return t2; } } 

<p>

il vincolo “where t: icomparable” dice che gli oggetti t1 e t2 sono classi che implementano la classe icomparable. grazie a questo possiamo usare il metodo “compareto” che altrimenti non sarebbe disponibile in quanto il compilatore non ha garanzie della sua esistenza su una classe che non implementi icomparable.

nel prossimo post parlerò di attribute, event e type forwarding.

Inserito da: msolcia | Settembre 1, 2008

Zaino Logitech Kinetik 15.4

Dopo 4 anni di glorioso servizio ho abbandonato il mio zaino Sansonite (SAHORA) sostituendolo con il Logitech Kinetik 15.4.

Logitech è conosciuta per gli accessori come web-cam, mouse (come il mio ormai irrinunciabile Mouse Logitech MX Revolution) e quindi mi sono stupito quando ho visto questo zaino pendere dalla rastrelliera di un famoso negozio di elettronica.

La cosa che più balza all’occhio è “la scocca” in poliuretano che è una vera e propria conchigliona proteggi laptop. Appena l’ho visto mi è piaciuto: senzazione di robustezza, colore professionale ma non troppo (blu scuro nella parte esterna ed arancio nella parte aderente alla schiena) e la presenza di numerose tasche e comparti per i miei innumerevoli accessori IT (ad esempio il porta Ipod nello spallaccio destro di cui ho sempre sentito la mancanza nel mio vecchio Sansonite).

E’ ormai un mesetto che lo uso e mi trovo bene anche se proprio con l’uso quotidiano ho potuto trovare qualche pecca:

– La tasca per il PC è un po’ piccola, va bene che si chiama Kinetik 15.4 ma se dovessero cambiarmi il PC aziendale con uno degli ultimi modelli che ho visto, dubito potrei usarlo ancora!

- Sempre la tasca del PC è posta in una posizione scomoda, in quanto l’accesso ad essa è alle volte ostruito dal contenuto di un’altra piccola taschina in alto (dove pongo gli occhiali da sole).

- Le cerniere non mi sembrano di buona qualità, fanno fatica a scorrere.

- Le taschine sono comode per classificare le varie cose ma alle volte mi sembra di non saper dove mettere le cose più ingombranti, ad esempio il mio vecchio Sansonite aveva tre tasche ma molto capienti anche se effettivamente pieni di oggetti alla rinfusa.

- la parte in poliuretano nei bordi ha già qualche raschiatura (non ricordo di essere passato di fianco a muri!!) che lascia intravere un materiale bianco.

Tornando ai pregi:

- ottimo bilanciamento quando lo si posa a terra,

- ottima protezione per il PC,

- comodi gli spallacci e tutta la struttura a contatto con la schiena,

- da sicuramente l’idea di robustezza (ad esempio il maniglione superiore)

- comode le taschine per organizzare meglio le cose (con lo svantaggio elencato sopra),

- Il tessuto sembra di qualità anche se il tempo mi darà il responso 

Riguardo al prezzo vi è poi una cosa curiosa che mi è successa:

stesso modello in un negozio l’ho visto a 99 euro, nell’altro a 43. Solo oggi ho visto che in Internet il prezzo in dollari è di 99$ questo forse spiega l’accaduto, certo rimane il dubbio che qualcuno voglia fare il furbo!

Ah naturalmente io ho preso quello a 43 :-)

Nel complesso al momento gli darei un bel 8 anche per il rapporto qualità/prezzo.

Magari tornerò su questo psot dopo un anno di intenso uso e vedremo se sarò ancora della stessa idea.

Inserito da: msolcia | Luglio 6, 2008

Saper creare oppurtunità e saperle sfruttare

Leggendo questo post mi sembra di vedere la mia situazione. Negli anni scorsi mi sono visto sfuggire varie “occasioni” per crescere professionalmente semplicemente perché avevo “giù il crapone” occupato a lavorare, lavorare, lavorare, mentre intorno a me c’è qui faceva “carriera” prendendo al volo incarichi più importanti.

Ho sempre pensato che nessuno mi avesse mai dato una possibilità proprio perchè da me si richiedeva di far andare avanti le cose operativamente. In realtà la colpa è soltanto nostra (mia e di chi leggendo si immedesima in questa situazione!): se sei occupato non hai tempo di “elevarti”, di guardare le cose dall’esterno e di ragionare più limpidamente, sei solo occupato a correre, sviluppare, testare, fare il tuo solito lavoro per cui tutti ti reputano bravo: sono convinto che un tecnico troppo bravo rimane tale, mentre i tecnici mediocri fanno i PM. Non me ne abbiano a male i PM, non sto stando giudizi di merito, la mia affermazione vuol semplicemente dire che alle volte non siamo noi che scegliamo il lavoro ma è il lavoro che sceglie noi.

Il post di Eric Brechner mi piace perchè espone le cose con lo stile diretto del suo alter-ego “I. M. Wright”. Lui la chiama “Ciecità non intenzionale”: il cervello è occupato / concentrato sui doveri giornalieri da non notare le numerose oppurtunità che sbocciano e qualcun’altro “non cieco” sfrutta.

Come fare per riavere la vista? Eric da alcuni consigli che riassumo qui sotto. Trovo alcuni di essi troppo orientati a mantenere un ruolo da tecnico, mentre altri come 2), 5) e 6) mi sembrano più generali e vorrei tentare di metterli in pratica.

1) Lavorare per sviluppare le funzionalità più importanti.

2) Capire meglio il business del cliente. Meglio lo si comprende più facile sarà identificare le funzionalità più importanti al punto 1),

3) Funzionalità critiche come la preparazione del setup, delle patch, dei sistemi che assicurano la compatibilità, l’accessibilità sono solitamente prese poco in considerazione dai tecnici, ma sono invece fondamentali per l’end-user.

4) Partecipare a task forces, comitati, mette in gran luce le persone.

5) Migliorare i processi e gli strumenti, ma non i propri! Guardare gli altri e capire come fare propri questi processi e strumenti e migliorarli rendendoli a disposizione del team e di tutta l’azienda.

6) I problemi sono opportunità. Anche solo cercare di risolverli porta vantaggi.

Un’altra parte del post che fa sicuramente riflettere è quando Eric dice che: “Accettare lo status quo permette di evitare problemi, ignorare le opportunità ed essere mediocre è sempre la scelta più semplice”. Difendersi da questa critica dicendo di non aver tempo è una scusa: nessuno di noi ha abbastanza tempo per fare tutte le cose che vorrebbe/dovrebbe fare. Si tratta solo di scegliere, di dare una priorità alle cose: tagliare le interruzioni o le attività che non sono importanti per potersi focalizzare su attività che facciano la differenza per il nostro business, per i nostri clienti ed in fine per noi, per la nostra carriera. E ora si tratta di mettere in pratica tutto ciò, semplice no??

Inserito da: msolcia | Giugno 9, 2008

Reference types (Esame 70-536)

A differenza dei value types visti nel post precedente, una variabile di tipo reference types non contiene direttamente il valore, ma bensì memorizza nello stack un indirizzo di memoria (puntatore) che si riferisce ad una zona di memoria chiamata heap in cui si trova l’oggetto.

L’heap viene gestito dal runtime attraverso un processo chiamato garbage collector, questo si occupa di gestire la memoria rendendola disponibile ai processi che la richiedono e sottraendola (dispose) a quei processi che non ne hanno più bisogno.

Assegnare una variabile A di tipo reference type ad un’altra variabile B di tipo reference type non crea una seconda copia dell’oggetto, ma bensì copia il valore del puntatore, dunque entrambe le variabili A e B punteranno al medesimo indirizzo di memoria nel heap.

Vi sono numerosi tipi reference built-it, i più comuni sono:

  • System.Object: è il tipo più generale. Ogni tipo può essere convertito in un System.Object
  • System.String: rappresenta una stringa di testo. Questo tipo nonostante sia un reference types viene gestito dal sistema come fosse un value type, cioé il runtime ad ogni cambiamento della stringa di testo libera la memoria e crea una nuova istanza della stringa. Per questo motivo il tipo System.String è detto immutabile (immutable). Questa creazione e distruzione delle stringhe, fatta silenziosamente dal runtime causa un certo overhead che può essere evitato usando un oggetto di tipo StringBuilder, descritto di seguito. Metodi più usati: Join, Split, Format,

 

  • System.Text.StringBuilder: stringa di testo dinamico. Un oggetto di questo tipo parte con 16 bytes (allocati dal costruttore di default) che poi possono crescere al variare della lunghezza della stringa. Non essendo un tipo immutabile, il variare della lunghezza della stringa non causa creazione/distruzione; questo tipo è dunque da preferire al tipo System.String quando si lavora con stringhe dinamiche

 

  • System.Array: è la classe base per tutti gli array. In C# un array si definisce ponendo di fianco al tipo le parentesi quadre. Metodi più usati: Sort.

 

Es.

int[] a = {1,2,3}

  • System.IO.Stream: uno stream è una sorta di buffer usato per qualsiasi operazione di lettura/scrittura da un file/device/network. Esistono tipi specifici per file (FileStream), memoria (MemoryStream), leggere da file di testo (StreamReader), scrivere su file di testo (StreamWriter). Esempio di scrittura su file di testo:

 

StreamWriter sw = new StreamWriter ("prova.txt");

sw.WriteLine("Ciao a tutti!");

sw.Close();

Esempio di lettura del file di testo appena scritto:

StreamReader sr = new StreamReader (“prova.txt”);

Console.WriteLine(sr.ReadToEnd());

sr.Close();

  • System.Exception: un’eccezione è un evento "eccezionale" che può accadere durante l’esecuzione di un sofware. Tali eventi “eccezionali” devono essere correttamente gestiti dal software pena ulteriori malfunzionamenti più gravi. La clausola try consente di monitorare un blocco di codice, la clausola catch consente di “intrappolare” un certo di tipo di eccezione che si sia verificata durante l’esecuzione del codice monitorato. Dunque se durante l’esecuzione del codice contenuto nel blocco try viene sollevata un’eccezione, il flusso di esecuzione passa al blocco catch corrispondente al tipo di eccezione. Esistono  diversi classi di eccezione: il framework mette a disposizione svariate classi tutte derivate da System.SystemException (esempio: System.IO.FileNotFoundException, System.UnauthorizedAccessException), ma è anche possibile creare delle proprie classi derivandole da System.ApplicationException. A fronte di un blocco try vi possono essere uno o più blocchi catch ciascuno per intrappolare un determinato tipo di eccezione.

    Il runtime eseguirà solo le istruzioni del primo blocco catch che soddisfa la tipologia di eccezione sollevata. Per questo motivo l’ordine delle catch è importante, bisogna porre i tipi di eccezione dalla più specifica alla più generica (Exception Filtering). Oltre a try e catch è possibile dichiarare un blocco finally che verrà eseguito alla fine del blocco try o, nel caso si sia verificata una eccezione, alla fine del corrispondente blocco catch. Poichè il blocco finally è sempre eseguito esso viene usato per fare il dispose di oggetti o chiudere connessioni, stream aperti. E’ buona norma che tutto il codice (ad eccezione della dichiarazione delle variabili) sia contenuto in un blocco try.

Per i reference types è tutto.

Dopo le classi built-in che sinora abbiamo visto, il prossimo post descriverà gli strumenti che .NET e C# ci mettono a disposizione per creare proprie classi, che per contrapporle ai tipi built-in possiamo chiamare custom classes.

Inserito da: msolcia | Giugno 3, 2008

Value types: built-in, structs, enum (Esame 70-536)

Come dicevo in questo post voglio darmi da fare per conseguire la certificazione “MCTS: .NET Framework 2.0 Distributed Applications” e passare poi alla “MCPD: Windows Developer On Visual Studio 2005″.

Ma sto volando troppo con il pensiero. Una cosa alla volta e dunque iniziamo subito con le basi, “i fondamentali”:

Il “value types” è il tipo più semplice che esiste nel .NET framework, una variabile di questo tipo contiene direttamente il valore (nessun puntatore ad altre aree di memoria) e viene memorizzata nello stack. Vi sono tre tipi di value types, tutti ereditano dalla classe astratta System.ValueTypes:

  • tipi built-in: questi sono i tipi base del .NET framework, ad esempio tutti i tipi numerici:

System.SByte (C# alias sbyte): signed byte values (1 byte)

System.Byte (C# alias byte): unsigned byte values (1 byte)

System.Int16 (C# alias short): signed integer (2 byte)

System.Int32 (C# alias int): signed integer (4 byte)

System.UInt32 (C# alias uint): unsigned integer (4 byte)

System.Int64 (C# alias long): signed integer (8 byte)

System.Single (C# alias float): floating point number (4 byte)

System.Double (C# alias double): precise or large floating point number (8 byte)

System.Decimal (C# alias decimal): financials and scientific calculation (16 byte)

Di tutti questi tipi buona norma usare Int32, UInt32 e Double che danno migliori prestazioni poichè ottimizzati da runtime/hw. [Nota: da più parti ho letto che è meglio usare gli alias forniti dal linguaggio che ho messo tra parentesi]. Vi sono anche i tipi non numerici:

System.Char (C# alias char): a unicode char (2 byte)

System.Boolean (C# alias bool): true/false (4 byte) (e qui non capisco come mai occupi così tanti byte, quando basterebbe un bit!!)

System.IntPtr: pointer (il numero di byte dipende dalla piattaforma 32bit/64bit)

System.DateTime: rappresenta un momento temporale data-tempo (8 byte)

Una caratteristica importante dei tipi build-in è l’Implicit Constructor, cioè non serve usare new per creare una nuova istanza del tipo, è sufficiente dichiarare una variabile di un certo tipo per avere l’istanza. Il framework inoltre assegna un valore di default ma richiede comunque che vi sia una inizializzazione esplicita.

Una cosa che non sapevo è che è possibile inizializzare a null una variabile di tipo ValueTypes nel modo seguente:

Nullable<bool> b = null;

o anche nella forma abbreviata che usa ‘?’ (solo per C#):

bool? b = null;

Una variabile Nullable mette a disposizione le due proprietà HasValue (per controllare se vi è un valore diverso da null) e Value. 

  • tipi user-defined (structs)

I tipi user-defined chiamati anche structs dal nome della keyword che serve a definirli, sono simili alle classi, nel senso che sono costituiti da un insieme di dati + operazioni. La differenza rispetto alle classi è che le strutture (dai la traduzione ci può stare) come tutti i tipi ValueTypes sono memorizzate direttamente (senza puntatori) nello stack e sono dunque più efficienti.

Ma allora quando usare una struct invece di usare una classe? Ecco alcune regole:

    • Quando l’oggetto logicamente rappresenta un singolo valore (es. una coordinata tridimensionale, si veda sotto)
    • Ha una dimensione minore di 16 bytes
    • La struttura dell’oggetto non verrà cambiata dopo la creazione,
    • Non è necessario fare un cast dell’oggetto a reference type

 

Un esempio di structs presente nel framework è System.Drawing.Point

Questo invece l’esempio di definizione di una struct:

struct Coord3D
    {
        int _x;
        int _y;
        int _z;

        public Coord3D(int x, int y, int z)
        {
            _x = x;
            _y = y;
            _z = z;
        }
    }

e di uso:

Coord3D coordinate;
coordinate = new Coord3D(1,2,3);

  •   enumerativi (enum)

Molto spesso si ha esigenza di codificare dei simboli con dei valori numerici fissi, solitamente perchè quest’ultimi consumano meno bytes.

Ad esempio supponete di dover memorizzare su un database il giorno della settimana corrente. In italiano il nome più lungo è mercoledì che ha 9 caratteri = 18 byte in unicode. Se invece di sprecare 18 byte creassimo una codifica che associa ad ogni giorno un numero da 1 a 7, risparmieremmo nel nostro caso ben 17 byte.

Questa codifica va poi però documentata da qualche parte, sarebbe bello poterlo fare proprio all’interno del codice: gli enumerativi permettono proprio questo.  Qui di seguito l’enumerativo che rappresenta i giorni della settimana (in inglese):

enum dayOfWeek : int
        { Monday = 1, Tuesday, Wednesday, Thurdsday, Friday, Saturday, Sundat };

Dunque lo scopo degli enumerativi è quello di migliorare la leggibilità del codice, consentendo a chi utilizza un certo tipo di poter scegliere tra una lista limitata di valori.

Prossima lezione “Reference type”

Inserito da: msolcia | Maggio 29, 2008

Certificazione Microsoft (esame 70-536)

Mi voglio certificare! Sono anni che ci penso, che tentenno, ma ora che sono qui in R&D il framework è divenuto il pane di tutti i giorni e dunque vai con lo studio.

Sono ancora indeciso se conseguire la “MCTS: .NET Framework 2.0 Distributed Applications” o la “MCTS: .NET Framework 2.0 Windows Applications“. La prima mi sembra più longeva rispetto alla seconda che principalmente si basa su sviluppi WinForm (no WPF per intenderci). Visto comunque che  l’esame 70-536 è core per entrambe direi di rimandare la decisione più avanti e per il momento parto con questo.

Mi sono procurato il libro “MCTS Self-Paced Training Kit (Exam 70-536): Microsoft .NET Framework 2.0 – Application Development Foundation” e ho già dato una prima lettura delle 1000 e oltre pagine (una lettura un po’ veloce!).

Parto ora con la seconda lettura che vorrei accompagnare con una serie di post su imitazione dei tanti che lo hanno già fatto e precisamente qui (Marco) e qui (Igor: ciao vecchio collega!). Scrivere qui mi darà l’occasione di ripetere gli argomenti con l’intento di fissarli nella mia testa (esattamente come quando ero a scuola :-) . Inoltre i post potranno, spero, anche risultare utili a chi, come me, vuole cimentarsi in questa avventura.

Interessante un commento ai post precedentemente citati, che informa dell’esistenza di una errata corridge del libro direttamente sul sito Microsoft. La terrò in considerazione.

Inserito da: msolcia | Maggio 28, 2008

Grazie San Google, ma come facevamo senza?

Alle volte mi domando come facevamo prima dell’avvento di Google (o dei motori di ricerca in generale). Certo sono quelle domande tipo “come facevamo senza cellulare?”, “come facevamo senza skype?”, va beh in qualche modo facevamo, certo che ora è molto comodo!!!

Per esempio oggi cercando di fare la build della soluzione Visual Studio 2005 alla quale stiamo lavorando (costituita da una ventina di progetti + un web service), ottenevo il seguente  errore:

Error    101    Invalid access to memory location. (Exception from HRESULT: 0×800703E6) sul file Web.Config

clip_image001

Nonostante il consiglio di un collega di rimuovere la seguente riga dal Web.Config, la soluzione continuava a non compilare.

<add assembly=”Microsoft.SqlServer.Replication, Version=9.0.242.0, Culture=neutral, PublicKeyToken=89845DCD8080CC91″/>

Una rapida ricerca tramite Google mi ha portato su pagine di sventurati come me avevano il problema e che consigliavano mille diversi work-around.

Alla fine ho scelto quello ufficiale di Microsoft che trovate qui.

In pratica bisogna si eliminare la riga sopra dal Web.Config ma bisogna anche copiare il file “Microsoft.SqlServer.Replication.dll” sotto la directory di build del web service. Nella mia macchina il suddetto file si trova sotto “C:\Program Files\Microsoft SQL Server\90\SDK\Assemblies”

Viva Google, Santo Subito :-D

Inserito da: msolcia | Aprile 24, 2008

2 Mesi son passati!!!!!!

“21 Febbraio” questa la data del mio ultimo post!! “Incredibile come passa il tempo quando ci si diverte” direbbe qualcuno.

A dire il vero sono sempre stato convinto che i mesi di Marzo, e soprattutto Aprile, avessero la particolarità di far trascorrere il tempo più velocemente. Ricordo ad esempio a militare di essermi piacevolmente trovato a fine Aprile come se da lì a Capodanno fosse passato solo 1-2 mesi e non 4. Se pensate che a militare si contavano i giorni che rimanevano dalla fine, è cosa alquanto strana. Tutto ciò è chiaramente una mia percezione, forse quest’anno amplificata dalla Pasqua anticipata.

Comunque ci eravamo lasciati a fine febbraio e da allora un bel po’ di cose sono successe:

- Leonardo cresce ed ora è inarrestabile: distrugge i nonni in settimana e noi nel week-end. Per il momento gli manca solo la parola, nel senso che a parte grugniti e versetti non spiccica niente di comprensibile, anche se si fa capire benissimo quando vuole qualcosa :-D .

- Lavorativamente tutto fantastico. Ora siamo (io e un nuovo collega) entrati nel vivo della fase di implementazione che prosegue a suon di .NET, C#, ADO.NET, PPS, VSTS, SQLServer 2005, Analysis Services … insomma non ci si annoia, anche perchè devo colmare il grande gap di conoscenza. A proposito mi stava venendo la tentazione di prendeermi qualche certificazione Microsoft.. vedremo.

- Io e Francesca invece l’ultimo week-end di Febbraio, abbiamo fatto un bel week-end in giro per l’Emilia,  con tanto di notte passata nella torre di guardia del castello medioevale di Vigoleno. Se ci andate vi consiglio la stanza Ginevra Degli Artisti (correzione dell’attentissima moglie!) quella in cui abbiamo dormito noi (sicuramente la + suggestiva). Abbiamo quindi proseguito con le visite di Castell Arquato e la Rocca di Soragna, bei posti (naturalmente tutto documentato su Flickr).

E già che siamo in vena di viaggi: domani partiamo per le Fiandre. Un po’ per il ponte, un po’ per consumare i numerosi punti Millemiglia (sinché si può). Su in Belgio è un po’ freddino, speriamo almeno non piova, visto che quando ci andavo per lavoro c’era sempre un tempo di bip.

Con questo post mi sono scatenato: pochi contenuti tecnologici ma in qualche modo dovevo riprendere il ritmo della scrittura. Staremo a vedere al mio ritorno…

« Articoli più recenti - Articoli precedenti »

Categorie