Deník C# design týmu – duben 2014

Ondřej Janáček       12.05.2014       C#       10958 zobrazení

Od chvíle, kdy se Roslyn stal open-source projektem, jsou vedle jeho repositáře k dispozici, mimo jiné, také shrnutí zasedání C# a VB.NET design týmů. Máte tedy možnost nejen vidět, čím se zrovna zabývají, ale můžete jejich rozhodnutí ovlivňovat Vašimi názory. Tato série článků bude sloužit jako rychlý přehled aktuálního dění v budoucí verzi jazyka C# (zatím označované 6.0).

Pokud preferujete angličtinu a rozhodnutí podpořená delším vysvětlením a protipříklady, originální verze jsou k dispozici na codeplexu Roslynu. Pokud Vám náhodou unikly zatím zveřejněné novinky, můžete si o nich přečíst v mém článku Co přinese C# 6.0.

Indexed members

Tato vlastnost nesklidila zrovna nadšené ohlasy. Pár zastánců si našla, ale většina vývojářů je popuzena tím, že by se syntaxe x.$y dostala do jazyka.

var customer = new JsonData
{
    $first = "John", // => ["first"] = "John"
    $last = "Doe" // => ["last"] = "Doe"
};
 
string first = customer.$first; // => customer["first"]

Rozhodnutí týmu? Odebrat.

Null propagating operator

string name = GetCustomer()?.Name;
// namísto
var temp = GetCustomer();
string name = (temp == null) ? null : temp.Name;

postupně dostává finální podobu. Řeší se zejména idiomatika, aktuálně asociativita operátoru, aby bylo pro jednoduché i složité případy na první pohled jasné, co je výsledkem výrazu.

Assignment to getter-only auto-properties

Pro pohodlnější vytváření immutable typů budou sloužit getter-only auto-properties

public string Id { get; }

Pokud chceme toto dnes, musíme udělat následující

private readonly string id;
public string Id { get { return id; } }

a nastavit id v konstruktoru nebo jej inicializovat přímo v deklaraci, což není zdaleka tak pohodlné. V nové verzi je tedy možné takovou property nastavit z primary konstruktoru nebo v deklaraci.

public class Customer(string id)
{
    public string Id { get; } = id;    
}
// nebo
public string Id { get; } = "Id123";

Občas se ale stane, že se budeme potřebovat vrátit k normálnímu konstruktoru a nastavit tuto property z něj. Rozhodnutí týmu? Getter-only auto-properties bude možné inicializovat i z normálního konstruktoru za cenu mírně odlišného chování. Hodnota se přiřadí do automaticky generovaného privátního backing field (třídní proměnná) dané property. Proč mírně odlišné chování? Protože property se setterem se budou stále nastavovat zavoláním setteru, nikoliv přímým zápisem do backing fieldu.

public class Customer
{
    public string Id { get; }

    public Customer(string id)
    {
        Id = id;
    }
}

Primary constructor body

Nejvíce otázek ohledně primary konstruktoru bylo okolo jejich těla. Aktuálně nedovolují například validaci argumentů, což je škoda. Vymyslet řešení nebylo složité.

public class Customer(string id)
{
    {
        if (id == null) throw new ArgumentNullException("id");
    }
    public string Id { get; } = id;
}

Co ovšem vyvolalo diskuzi je interpretace tohoto bloku. V jaké fázi konstrukce objektu se bude volat? První možnost byla initializer body, který by se volal ještě před voláním do báze, nebyl závislý na primary konstruktoru a mohlo by jich být více. Druhá možnost, constructor body na druhou stranu na primary konstruktoru závislý je, může být jen jeden a volá se až po volání do báze. Jako vítěz vzešla právě druhá možnost, protože je více intuitivní.

Initialization scope

Initialization scope je nový prostor, ve kterém lze přistupovat k parametrům primary konstruktoru. Vznikl zejména proto, aby umožnil vytvoření třídní proměnné pojmenované stejně, jako parametr primary konstruktoru, bez vzniku chyby. To znamená, že pokud Vám nevyhovuje primary constructor field parameter, pak stále můžete využívat třídní proměnné a inicializovat ji z primary konstruktoru.

// automaticky vygeneruje privátní třídní proměnnou pojmenovanou id
// private string id = primary constructor field parameter
public class Customer(private string id)
{
}

// následující teď zatím možné není, ale bude
// je to trochu zavádějící, ale alespoň trochu podobné this.id = id
public class Customer(string id)
{
    private string id = id;
}

A co tato novinka umožní? Například následující definici třídy (ukázka z ofic. zdroje).

public class ConfigurationException(Configuration configuration, string message) 
    : Exception(message)
{
    private Configuration configuration = configuration;
    public bool IsRemote { get; } = (var settings = configuration.Settings)["remote"];
    public bool IsAsync { get; } = settings["async"];
}

Líbí se Vám to? Jste zděšení? Máme možnost se k tomu vyjádřit nejen v komentářích pod tímto článkem, ale hlavně v diskuzi deníku design týmu.

 

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.

                       
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