Tag Archives: VS2015

C# 6.0: String interpolation – zkrácený String.Format() [5/10]

Velmi často používaná metoda String.Format() získala v C# 6.0 syntaktic-sugar v podobě zkráceného zápisu, který má být přehlednější a méně náchylný na chyby:

// C# 5.0
var s = String.Format("{0} is {1} year{{s}} old", p.Name, p.Age);

// C# 6.0 cílová podoba s $ na začátku
var s = $"{p.Name,20} is {p.Age:D3} year{{s}} old";

// C# 6.0 ve VS2015 Preview
var s = "\{p.Name} is \{p.Age} year{s} old";

Půjde samozřejmě použít i další formátovací instrukce, např.

var s = $"{p.Name,20} is {p.Age:D3} year{s} old";
var s = $"{p.Name} is {p.Age} year{(p.Age == 1 ? "" : "s")} old";

Série článků o novinkách v C# 6.0:

  1. Auto-property initializers a getter-only (read-only) auto-properties
  2. Expression-bodied function members
  3. Using static
  4. Null-conditional operators (?., ?[], …)
  5. String inerpolation – zkrácený String.Format()
  6. nameof() expressions
  7. Index initializers – přehlednější inicializace slovníků
  8. Exception filters, await v catch/finally blocích
  9. Konstruktor struct bez parametrů
  10. Ostatní (extension-Add v initializers, overload resolution)

C# 6.0: Null-conditional operators ?. [4/10]

Asi nejočekávanější a nejžádanější nová konstrukce C# 6.0 spočívá ve zkráceném zápisu testů na null. Nové null-conditional operátory lze zkráceně popsat jako „pokud před otazníkem není null, pokračuj za otazníkem, jinak null“:

int? length = customers?.Length; // null, pokud customers je null
Customer first = customers?[0]; // null, pokud customers je null

Velmi častá pak bude kombinace s ?? operátorem (coallesce):

int length = customers?.Length ?? 0; // 0, pokud customers je null

Vyhodnocení je samozřejmě zkrácené, pokud je před otazníkem null, pokračování za otazníkem se vyhodnocuje/spouští, pouze pokud nejde o null. Pokud potřebujeme testů více, musíme operátor použít vícekrát:

int? first = customers?[0].Orders?.Count();

Hezky lze chování operátoru (při null se část za otazníkem neprovádí) využít například pro volání delegátů/událostí. Nepoužívá se zde syntaxe, kde by za otazníkem následovaly přímo závorky volání metody, ale jde se přes metodu Invoke():

PropertyChanged?.Invoke(this, args);

Lze samozřejmě dále kombinovat a dostat se na konstrukce typu

if (predicate?.Invoke(e) ?? false) { … }

Série článků o novinkách v C# 6.0:

  1. Auto-property initializers a getter-only (read-only) auto-properties
  2. Expression-bodied function members
  3. Using static
  4. Null-conditional operators (?., ?[], …)
  5. String inerpolation – zkrácený String.Format()
  6. nameof() expressions
  7. Index initializers – přehlednější inicializace slovníků
  8. Exception filters, await v catch/finally blocích
  9. Konstruktor struct bez parametrů
  10. Ostatní (extension-Add v initializers, overload resolution)

C# 6.0: Using static [3/10]

Pomůcka, která vám umožní příkazem using „zpřístupnit“ statickou třídu tak, že lze volat její statické metody bez explicitního uvádění jména třídy:

using System.Console;
using System.Math;

class Program
{
    static void Main()
    {
        WriteLine(Sqrt(3*3 + 4*4));
        // odpovídá Console.WriteLine(Math.Sqrt(3*3 + 4*4));
    }
}

Zkrácenou syntaxi je samozřejmě možné použít jen tehdy, pokud je použitá metoda jediná.

Situace u extension metod

Extension metody jsou definovány na statické třídě, nová using konstrukce tím pádem umožňuje jemnější „zpřístupňování“ extension metod jednotlivých statických tříd aniž bychom museli zpřístupnit celý namespace jako dosud.

using System.Linq.Enumerable; // Dotahujeme pouze jednu třídu extension-metod, ne celý namespace

class Program
{
    static void Main()
    {
        var range = Range(5, 17); // Ok: není extension metoda, ale běžná statická
        var odd = Where(range, i => i % 2 == 1); // Chyba, extension-metodu takto volat nelze
        var even = range.Where(i => i % 2 == 0); // Ok, extension metoda
    }
}

Using-konstrukce samozřejmě z extension metody neudělá běžnou statickou metodu, přímo zkrácenou syntaxí je tedy volat nelze.

Mimochodem dosud bylo možné bez obavy změnit běžnou statickou metodu na extension metodu a nemuseli jsme se obávat, že něco přestane fungovat. Nyní již si nemůžeme být jisti, protože pokud by někdo běžnou statickou metodu volal bez uvedení třídy (pomocí nového using static), tak změnou této metody na extension-metodu přestane takový kód být kompilovatelný.

Série článků o novinkách v C# 6.0:

  1. Auto-property initializers a getter-only (read-only) auto-properties
  2. Expression-bodied function members
  3. Using static
  4. Null-conditional operators (?., ?[], …)
  5. String inerpolation – zkrácený String.Format()
  6. nameof() expressions
  7. Index initializers – přehlednější inicializace slovníků
  8. Exception filters, await v catch/finally blocích
  9. Konstruktor struct bez parametrů
  10. Ostatní (extension-Add v initializers, overload resolution)

C# 6.0: Expression-bodied function members [2/10]

Expression-syntaxi s „lambda-šipkou“, kterou známe již z běžného kódu u lambda výrazů, je nyní možné ji použít i pro zápis těla metody, getteru nebo obdobné situace (např. operátoru).

Použití pro metody, operátory a typové konverze

public Point Move(int dx, int dy) => new Point(x + dx, y + dy);
public static Complex operator +(Complex a, Complex b) => a.Add(b);
public static implicit operator string(Person p) => p.First + " " + p.Last;

Výsledek je stejný, jako by metoda měla klasické tělo s blokem a v něm samotný return příkaz.

Syntaxi lze použít, o pokud metoda „vrací“ void, nebo u asynchronních metod vracejících Task, stejně jako u lambda-výrazů:

public void Print() => Console.WriteLine(First + " " + Last);

Použití pro getter property a indexer

Syntaxi lze použít i pro zkrácený zápis getteru property (property pak nemůže mít setter), nebo pro indexer:

public string Name => First + " " + Last;
public Customer this[long id] => store.LookupCustomer(id);

Série článků o novinkách v C# 6.0:

  1. Auto-property initializers a getter-only (read-only) auto-properties
  2. Expression-bodied function members
  3. Using static
  4. Null-conditional operators (?., ?[], …)
  5. String inerpolation – zkrácený String.Format()
  6. nameof() expressions
  7. Index initializers – přehlednější inicializace slovníků
  8. Exception filters, await v catch/finally blocích
  9. Konstruktor struct bez parametrů
  10. Ostatní (extension-Add v initializers, overload resolution)

C# 6.0: Auto-property initializers a getter-only (read-only) auto-properties [1/10]

Preview Visual Studio 2015 a .NET 4.6 dnes vyšly, nastal tedy čas si v seriálu krátkých článků připomenout novinky v C# 6.0 (jednotlivé články zamýšlené série budou přibývat postupně):

RTM Update: Constructor struct bez parametrů byl z finální podoby C# 6.0 odstraněn.

  1. Auto-property initializers a getter-only (read-only) auto-properties
  2. Expression-bodied function members
  3. Using static
  4. Null-conditional operators (?., ?[], …)
  5. String inerpolation – zkrácený String.Format()
  6. nameof() expressions
  7. Index initializers – přehlednější inicializace slovníků
  8. Exception filters, await v catch/finally blocích
  9. Konstruktor struct bez parametrů – není součástí C# 6.0 RTM
  10. Ostatní (extension-Add v initializers, overload resolution)
  11. Primary constructors
  12. Declaration expression

Finální podoba C# 6.0 se může měnit, články vychází z informací z okamžiku vydání VS 2015 Preview – soupisu změn od Madse Torgersena, C# Language PM a ze stručného seznamu změn vedeného u projektu Roslyn.

V tuto chvíli k velkému smutku všech zúčastněných byly ze C# 6.0 odstraněny dvě oblíbené konstrukce, které již v CTP verzích fungovaly:

  1. Primary constructors  – public class Point(int x, int y)
  2. Declaration expressions – if (int.TryParse(input, out int output))

Dá se předpokládat, že cut-off v tomto případě znamená odklad do C# 7.0, i když může dojít i k zásadním změnám.

Initializers for auto-properties

Jde o syntaxi známou z běžných fieldů, jejíž použitelnost byla rozšířena na auto-properties:

public class Customer
{
    public string First { get; set; } = "Jane";
    public string Last { get; set; } = "Doe";
}

Ve skutečnosti dojde k inicializaci podkladového fieldu, na který se auto-property mapuje.

Getter-only auto-properties (readonly)

V předchozích verzích C# musela mít auto-property setter i getter. Nově lze definovat pouze getter a ve skutečnosti tím vznikne read-only podkladový field, který lze nastavit buď pomocí initializeru (viz výše) nebo z constructoru.

public class Customer
{
    public string First { get; } = "Jane";
    public string Last { get; } = "Doe";
}

Nabízí se zde použití pro immutable třídy, v nichž dosud zkrácenou syntaxi auto-properties nebylo možné využít.