C6[1]

Con il rilascio di Visual Studio 2015 preview verrà rilasciata anche la versione 6 di c#: le nuove funzionalità che verranno introdotte sono principalmente nell'ottica di semplificare e velocizzare la scrittura di codice.

La prima caratteristica della nuova versione di C# che andremo a vedere è l'operator "Null-Conditional".

Creiamo una semplice classe Libro e una classe Biblioteca.

        public class Libro
        {
            public string Titolo { get; set; }
            public string Autore { get; set; }
        }

        public class Biblioteca
        {
            public string NomeBiblioteca { get; set; }
            public IList<Libro> Libri { get; set; }
            public EventHandler

            public void AggiungiLibro(Libro libroNuovo)
            {
                Libri.Add(libroNuovo);
            }

            public string StampaNumeroLIbri()
            {
                return string.Format("La mia biblioteca contiene : {0}", NumeroLibri);
            }

            public int NumeroLibri
            {
                get {
                    return Libri.Count;
                }
            }

            public static Biblioteca GetCurrent()
            {
                var rnd = new Random();
                int rndNumber = rnd.Next(0, 10);

                return (rndNumber < 5) ? new Biblioteca { NomeBiblioteca = "DotNetCode" } : null;
            }

Andiamo a effettuare le prime operazioni sulla nostra biblioteca:

static void Main(string[] args)
{
try
{
var biblio = Biblioteca.GetCurrent();

if(Biblioteca!=null) Console.WriteLine(biblio.StampaNumeroLIbri());


}
catch (Exception ex)
{
Console.WriteLine("ERRORE : {0}", ex.Message);
Console.ReadLine();
}

}

Visto che il metodo statico GetCurrent può restituire anche null dobbiamo verificare che non sia nullo il nostro oggetto biblioteca prima di stamparne il numero di libro presenti.

Col nuovo operatore il nostro codice diverrebbe :

Console.WriteLine(biblio?.StampaNumeroLIbri());

Tutto quello che segue l'operatore ? verrà eseguito solo se l'istanza di biblio è diversa di null.

Facciamo conto che vogliamo fare un operazione di questo genere :

Console.WriteLine(biblio?.NomeBiblioteca.ToUpper().Trim());

In caso di istanza nulla del nostro oggetto non verrebbero eseguiti ne il ToUpper ne il Trim ma viene restituito un oggetto null.(n.b in caso di value type viene restituito il nullable del tipo stesso)

Quindi in caso che (biblio!=null) && (biblio.Libri == null) avremmo :

int? numeroLibri = biblio?.Libri?.Count();

L'operatore di null-conditional può essere usato anche con l'operatore indice [].

var mioLibro = biblio?.Libri?[0];

L'uso del nuovo operatore in concomitanza con il null-coalescing-operator ?? ci permette per esempio di fare questo :

var numeroLibri = biblio?.Libri?.Count ?? 0;

A questo punto numeroLibri non è più un int? ma un int.

Possiamo usare questi due operatori per definire due extension method :

    public static class Extension
    {
        public static T OrDefault<T>(this T istance, T defaultValue) where T :class
        {
            return istance ?? defaultValue;
        }
        public static T OrDefault<T>(this object istance) where T : struct
        {
            if (istance == null) return default(T);
            return (T)istance;
        }
    }

A questo punto possiamo scrivere :

Console.WriteLine((biblio?.StampaNumeroLIbri()).OrDefault("La biblioteca risulta essere vuota"));

Notare che ho dovuto scrivere ((biblio?.StampaNumeroLIbri()) in quanto se avessi scritto biblio?.StampaNumeroLIbri().OrDefault("La biblioteca risulta essere vuota") il metodo OrDefault non sarebbe stata eseguito in quanto facente parte della catena di esecuzione che segue l'operatore ?.

Racchiudendo tra parentesi ((biblio?.StampaNumeroLIbri()) chiudiamo la catena di esecuzione e quindi a questo punto abbiamo : null.OrDefault<string>("La biblioteca risulta essere vuota") e quindi in definitiva :

Console.WriteLine(null ?? "La biblioteca risulta essere vuota");

Il secondo metodo serve per gestire situazioni simili per i value type.

Quindi

var numeroLibri = biblio?.Libri?.Count ?? 0;

diventa

var numeroLibri = (biblio?.Libri?.Count).OrDefault();

L'operatore ? ci torna utile anche nelle chiamate a delegati.

Immaginiamo di dover gestire l'evento OnBookAdded.

public EventHandler OnBookAdded;

E modifichiamo di conseguenza il metodo AggiungiLibro

            public void AggiungiLibro(Libro libroNuovo)
            {
                (Libri ?? (Libri=  new List<Libro>())).Add(libroNuovo);
                var bookAdded = OnBookAdded;
                if (bookAdded != null)
                {
                    bookAdded(this, EventArgs.Empty);
                }
            }

Diventa

            public void AggiungiLibro(Libro libroNuovo)
            {
                (Libri ?? (Libri=  new List<Libro>())).Add(libroNuovo);
                OnBookAdded?.Invoke(OnBookAdded, EventArgs.Empty);
            }

Riepilogando tramite l'operatore ? noi abbiamo le seguenti funzionalità :

  • Null come dato di ritorno se l'operando è null
  • Se l'operando è null non vengono eseguiti gli eventuali metodi legati all'operando stesso
  • In caso di operando di tipi Value Type viene restituito un nullable del tipo stesso
  • La possibilità di chiamare un delegato senza assegnarlo a una variabile locale e senza dovere controllare che sia diverso da null
  • La possibilità di usarlo anche con l'operatore indice []







Autore:


blog comments powered by Disqus

 

Calendar

<<  ottobre 2017  >>
lunmarmergiovensabdom
2526272829301
2345678
9101112131415
16171819202122
23242526272829
303112345

Vedi i post nel calendario più grande

Category list