Tag Archives: VS2015

VS2015: Window Layout Management

Ač jsem dříve pracoval s více monitory, opustil jsem takový setup a po dlouhých rocích s 24″ 1920x1200px jsem dnes přešel (zatím „na zkoušku“) na 32″ panel 2560x1440px (Samsung S32D850T).

Rázem se ukázalo, že přechod mezi zadockovaným notebookem a jeho vlastním 1920×1080 nebude bezbolestný jako dosud, že uspořádání Visual Studia už bude potřeba nějak přepínat.

Pro starší verze VS byl potřeba doplněk, např. Layouts O Rama, ve Visual Studio 2015 je již vestavěno:

image

…synchronizuje se dokonce přes Microsoft Account, není již co řešit.

[Updated] VS2013, VS2015, VS2017: Když v code-behind nefunguje F7 pro přechod do markupu

VS2015 Update: Úplně stejně se mi chovalo VS2015 pro defaultní „Web Development (Code Only)“ sadu nastavení. Níže uvedený postup pomohl.

Nějakou shodou okolností mi Visual Studio 2013 přestalo reagovat na F7 pro přechod z code-behind text-editoru na ASPX-markup editor.

V nastavení jsem zjistil, že F7 je asociováno na command View.ViewCode (Global). Stačilo přidat pro kontext Text Editor command View.ToggleDesigner.

image

UPDATE: VS2017 úplně stejně.

C# 6.0: Ostatní (extension-Add v initializers, overload resolution) [10/10]

Do C# 6.0 se dostaly ještě dvě „drobotiny“, které většině vývojářů život nijak zásadně nezmění.

Collection-initializers podporují extension-podobu Add() metody

V C# 5.0, v inicializaci kolekcí, nemohla být použita extension-podoba metody Add(), přestože VB.NET toto měl. Byl to spíše bug/opomenutí. Každopádně nyní je to napraveno.

Vylepšené vyhodnocování overloadů

Drobná vylepšení, kterých si málokdo všimne. O něco málo méně míst, kde se můžete setkat s výtkou kompilátoru ohledně nejednoznačnosti volby overloadu (např. u nullable hodnotových typů parametrů, atp.)

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: Konstruktor struct bez parametrů [9/10] – vyřazeno z RTM

Tato úprava jazyka není součástí C# 6.0 RTM, byla odstaněna.

C# 5.0 nedovoluje vytvořit na struct explicitní constructor bez parametrů, hodnoty fieldů jsou totiž automaticky inicializovány svými default(T) hodnotami. C# 6.0 toto omezení odstraňuje:

struct Person
{
    public string Name { get; }
    public int Age { get; }
   
    public Person(string name, int age)
    {
        Name = name;
        Age = age;
    }

    public Person() : this("Jane Doe", 37)
    { }
}

Důležitým omezením však je, že takový konstruktor se použije pouze v případě explicitního volání new Person(), zatímco default(Person) stále založí výchozí hodnoty fieldů, stejnětak vytvoření pole new Person[..].

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: Exception filters, await v catch/finally bloku [8/10]

C# 6.0 dohání chybějící drobnosti kolem výjimek

Exception filters

Catch-blok je vyvolán, pouze pokud je vedle typu výjimky splněna i podmínka:

try
{
    … 
}
catch (MyException ex) if (condition) // už v podmínce se lze odkázat na ex
{
    …
}

Znásilnit tuto konstrukci lze i pro neinvazivní logování výjimek, sám bych s tím však byl opatrný.

private static bool Log(Exception e) { /* log it */ ; return false; }
…
try { … } catch (Exception e) if (Log(e)) {}

Await v catch a finally blocích

C# 5.0 nepodporoval await v catch a finally blocích, protože se Microsoft domníval, že to není potřebné a implementace by byla neúměrně komplikovaná. Nyní dlužnou funkčnost doplnili:

Resource res = null;
try
{
    res = await Resource.OpenAsync(…);
}
catch(ResourceException e)
{
    await Resource.LogAsync(res, e);
}
finally
{
    if (res != null) await res.CloseAsync();
}

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: Index initializers – přehlednější inicializace slovníků [7/10]

Jednou z předchozích novinek v C# byla možnost při založení kolekce/slovníku naplnit ho rovnou i počátečními hodnotami. C# 6.0 přichází se zpřehledněním zápisu pro inicializaci slovníků (a podobných objektů s indexery):

// C# 5.0
var numbers = new Dictionary<int, string> {
    {7, "seven"},
    {9, "nine"},
    {13, "thirteen" }
};

// C# 6.0
var numbers = new Dictionary<int, string> {
    [7] = "seven",
    [9] = "nine",
    [13] = "thirteen"
};

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: nameof() expressions [6/10]

Přestože se nová FluentAPI snaží vyhnout textovým řetězcům ve prospěch „strong-type“ zápisů, stále se na mnoha a mnoha místech setkáváme s potřebou zapsat do kódu textový řetězec, který odkazuje na název nějakého prvku. Potíže s tím související jsou nasnadě – kompilátor nám takový textový řetězec nekontroluje a jakýkoliv automatický refactoring v podobě přejmenování prvku zanechá textový řetězec nedotčen. Jde tak o častý zdroj chyb.

C# 6.0 přináší pomůcku, kterou se dá těmto problémům vyhnout. Konstrukci nameof(prvek) převede kompilátor na textovou konstantu odpovídající názvu prvku:

// C# 5.0
(if x == null) throw new ArgumentNullException("x");

// C# 6.0
(if x == null) throw new ArgumentNullException(nameof(x));

Uvnitř nameof() může být prakticky cokoliv, co má jméno – proměnná, typ, metoda, property, atp. Vždy se však použije pouze poslední část jména:

Console.WriteLine(nameof(person.Address.ZipCode)); // vrátí "ZipCode"
Console.WriteLine(nameof(System.Console.WriteLine)); // vrátí "WriteLine"

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: 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)