Co přinese C# 6.0?

Ondřej Janáček       6. 4. 2014       C#, .NET       7225 zobrazení

Ve dnech 2. – 4. dubna proběhla každoroční Microsoft konference Build 2014, která přinesla mnoho zajímavých novinek. Jednou z nich je také preview další verze jazyka C#, označována 6.0.

Zatím každá nová verze jazyka přinesla alespoň jeden nový rys, který změnil způsob, jakým vyjadřujeme naše úmysly pomocí kódu. Rychlá rekapitulace:

  • C# 2 – generika
  • C# 3 – LINQ
  • C# 4 – dynamic
  • C# 5 – async/await
  • C# 6 – ???

Co to bude v následující verzi zatím není známo, nicméně už teď je k dispozici hrstka cukru! Mám samozřejmě na mysli syntaktický cukr, neboli

“Označení pro takovou část syntaxe programovacího jazyka, jejíž jediným účelem je usnadnit programátorovi zápis nějakých základních obratů. Nejedná se tedy o klíčovou součást jazyka; nemá vliv na to, jaké programy v něm lze napsat nebo jak budou rychlé, nemá vliv ani na architektonický návrh programu.”

jak napovídá wikipedie. Konec obcházení okolo, zde jsou novinky!

Initializers and auto-properties

Konec inicializace auto-properties v konstruktoru nebo pomocí někdy jinak zbytečných privátních členů.

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

Primary constructors

Slouží většina Vašich tříd pouze jako úložiště hodnot? Nebo obsahuje konstruktor pouze inicializace proměnných jako v následující ukázce?

public class Customer
{
    private string first;
    private string last;

    public string First { get { return first; } }
    public string Last { get { return last; } }

    public Customer(string first, string last)
    {
        this.first = first;
        this.last = last;
    }
}

Teď lze zapsat konstruktor přímo jakou součást definice třídy a s využitím první zmíněné novinky je inicializace členů velmi stručná.

public class Customer(string first, string last)
{
    public string First { get; } = first;
    public string Last { get; } = last;
}

Using static

Je Vám to povědomé? To proto, že VB.NET už to dávno umí. Tak teď i C#.

using System.Console;
using System.Math;

class Program
{
    static void Main()
    {
        WriteLine(Sqrt(3*3 + 4*4));
    }
}

Mě osobně se tohle moc nelíbí. Dovedu si představit situace, kde to využiji, ale mnohem více mi vadí, že není na první pohled jasné, jestli volám metodu, která je součástí dané třídy, nebo je to statická metoda odjinud.

Declaration expressions

Co na to jen říct, než super! Líbí se mi vytvářet proměnné až v místě, kde je opravdu potřebuji.

if (int.TryParse(s, out int i)) { … }

GetCoordinates(out var x, out var y);

Console.WriteLine("Result: {0}", (int x = GetValue()) * x); 

if ((string s = o as string) != null) { … s … }

Jako jedinou stinnou stránku bych viděl to, že vytváření out parametrů bude tak snadné, že se budou používat mnohem více. Ne na darmo jsou metody navržené primárně tak, aby vraceli pouze jedinou hodnotu a pokud jich zpět chceme náhodou více, tak už to stojí trochu úsilí. Stejně jako s používáním typu Tuple je vhodné zamyslet se nad tím, kdy je lepší vytvořit typ, které více návratových hodnot zapouzdří.

Exception filters

Hurá! VB.NET je má, F# je má a konečně i C# se dočkal.

try { … }
catch (MyException e) if (myfilter(e))
{
    …
}

Indexed members and element initializers

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

var customer = new JsonData
{
    $first = "Anders",  // => ["first"] = "Anders"
    $last = "Hejlsberg" // => ["last"] = "Hejlsberg"
};

string first = customer.$first; // => customer["first"]

Sourhn

Dále je možné používat await v catch a finally blocích, což je vhodné zejména pokud při zachycení výjimky chcete volat potencionálně déle běžící operace a nakonec, inicializátory kolekcí, které v podstatě volají na kolekci metodu Add nyní mohou volat i extension metodu pojmenovanou Add.

Všechny ukázky jsou součástí dokumentu Upcoming Features in CSharp, který lze stáhnout v rámci Roslyn End User Preview přes http://roslyn.codeplex.com/ Je pravděpodobné, že Vás napadne spousta otázek k použití nových konstruktů a většina jich je popsána právě v tomto dokumentu.

Věřím, že si v těchto novinkách najdete něco, co byste rádi používali už teď a zároveň něco, s čím vůbec nesouhlasíte. Všechny tyto názory jsou teď pro C# design team důležitější víc než kdy jindy, protože poprvé máme my vývojáři šanci ovlivnit, co nakonec v jazyku nakonec bude a jakou to bude mít podobu. Proto si “REUP” nainstalujte, vyzkoušejte nové vlastnosti jazyka a řekněte Microsoftu, co si o tom myslíte (po stažení REUP se Vám v účtu na webu Microsoftu objeví tlačítka pro reportování bugů a odesílání feedbacků). Pokud se Vám žádná z nových vlastností nelíbí, nezoufejte. Spousta věcí ještě není naimplementovaných a současné mohou být upraveny na základě feedbacku komunity. Na výše uvedeném webu také můžete v sekci Documentation>CSharp Language Design Notes sledovat vývoj nových vlastností, jak budou přibývat a lze se i podívat, jakým vývojem prošli ty již implementované.

 

hodnocení článku

0       Hodnotit mohou jen registrované uživatelé.

 

Nový příspěvek

 

Příspěvky zaslané pod tento článek se neobjeví hned, ale až po schválení administrátorem.

Chybky

Super článek, ale bacha na tu shodu podmětu s přísudkem. :)

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Děkuji. Můžete ukázat na konkrétní místa, ať se poučím?

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Tak já si všiml těchto:

V Declaration Expressions pod kódem ve 2. řádku na konci: "aby vraceli" má být tvrdé.

V posledním řádku celého článku: "vývojem prošli ty již implementované" také tvrdé.

A v části Using static v prvním slově pod kódem má být "mně" místo "mě".

Jinak pěkný článek, ale je vidět, že se opravdu tým soustředil na přepisování kompilátoru, protože tyhle změny rozhodně nejsou nijak převratné.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Děkuju za opravy.

Ano, to jsou i slova členů Roslyn týmu. Některé novinky tam prý automaticky vznikly a oni se rozhodli je nezakázat. Jinde zase údajně stačilo přidat řádek kódu.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

INotifyPropertyChanged

Žádné revoluční novinky, ale hodí se. Ovšem u datových tříd implementujících rozhraní INotifyPropertyChanged, které jsou v XAML aplikacích (WPF, WP8, W8) potřeba nejčastěji, se vlastnosti budou muset zdlouhavě rozepisovat (zapouzdřovat fields) dál, aby se v set části mohla volat událost PropertyChanged.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Tohle řeší PostSharp.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Když si nainstalujete .NET Compiler Platform (Roslyn) Preview (v SDK), tak jeden ze samplů je tam Samples\CSharp\ImplementNotifyPropertyChanged. Ten by měl způsobit, že se to bude nabízet jako nový refaktoring.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Drobné doplnění

A ještě půjde deklarovat field přímo součástí definice třídy například:

public class Customer(string first, private readonly string last)
{
    public string First { get; } = first;	      //first je pouze parametr
    public string Last { get { return this.last; } }  //last je field
}

Jinak některé ty věci budou použitelné, ale osobně za největší a nejdůležitější považuji to zmíněné použití await uvnitř catch a finally. Naopak Using static je podle mě totální prasárna a je škoda, že to tam daj.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Jo, to jsem mohl uvést. Díky za doplnění.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Cilem "using static class" je

1) moznost importovat extension methods z dane tridy aniz se importuji metody z celeho namespace.

2) zprehlednit psani "domain specific" kodu.

Napriklad, pokud pisete hodne vzorecku a pouzivate funkce z tridy Math:

double a = ACosh(Cosh(B) * Cosh(c) - Sinh(b) * Sinh(c) * Cos(alpha + PI/2));

je jiste citelnejsi nez

double a = Math.ACosh(Math.Cosh(B) * Math.Cosh(c) - Math.Sinh(b) * Math.Sinh(c) * Math.Cos(alpha + Math.PI / 2));

Nebo jiny priklad, pri konstrukci Expression Tree:

var block = Expression.Block(
    new[] { result },
    Expression.Assign(result, Expression.Constant(1)),
        Expression.Loop(
           Expression.IfThenElse(
               Expression.GreaterThan(value, Expression.Constant(1)),
               Expression.MultiplyAssign(result,
                   Expression.PostDecrementAssign(value)),
               Expression.Break(label, result)
           ),
       label
    )
);

vs

var block = Block(
    new[] { result },
    Assign(result, Constant(1)),
        Loop(
           IfThenElse(
               GreaterThan(value, Constant(1)),
               MultiplyAssign(result, PostDecrementAssign(value)),
               Break(label, result)
           ),
       label
    )
);

Samozrejme je treba pouzivat z rozvahou. Napriklad omezit pouzivani jen na zdrojove soubory, kde to opravdu ma smysl. Jako kazdy konstrukt je mozne zneuzit i tento.

nahlásit spamnahlásit spam 0 odpovědětodpovědět
                       
Nadpis:
Antispam: Komu se občas házejí perly?
Příspěvek bude publikován pod identitou   anonym.

Nyní zakládáte pod článkem nové diskusní vlákno.
Pokud chcete reagovat na jiný příspěvek, klikněte na tlačítko "Odpovědět" u některého diskusního příspěvku.

Nyní odpovídáte na příspěvek pod článkem. Nebo chcete raději založit nové vlákno?

 

  • Administrátoři si vyhrazují právo komentáře upravovat či mazat bez udání důvodu.
    Mazány budou zejména komentáře obsahující vulgarity nebo porušující pravidla publikování.
  • Pokud nejste zaregistrováni, Vaše IP adresa bude zveřejněna. Pokud s tímto nesouhlasíte, příspěvek neodesílejte.

Příspěvky zaslané pod tento článek se neobjeví hned, ale až po schválení administrátorem.

přihlásit pomocí externího účtu

přihlásit pomocí jména a hesla

Uživatel:  
Heslo:  

zapomenuté heslo

 

založit nový uživatelský účet

zaregistrujte se

 
zavřít

Nahlásit spam

Opravdu chcete tento příspěvek nahlásit pro porušování pravidel fóra?

Nahlásit Zrušit

Chyba

zavřít

feedback