TOC

This article has been localized into Czech by the community.

Třídy:

Vlastnosti

V předchozím článku jsme diskutovali o polích. Jsou to jakési globální proměnné pro třídu, které vám umožňují přístup ze všech metod. Také jsme se stručně dotkli skutečnosti, že pole MOHOU být přístupná z jiných tříd, pokud jsou označena jako public, ale to obecně není doporučeno. Pro proměnné/pole, ke kterým si přejete přistupovat z vnějšku vaší třídy, byste místo toho měli použít vlastnosti.

Když deklarujete pole jako veřejné (public), dáváte mu úplný přístup zvenčí - jiné třídy s ním mohou dělat, co chtějí, bez jakéhokoli upozornění deklarující třídě. Vlastnosti vrací kontrolu zpět deklarující třídě tím, že specifikují, zda je pole pouze pro čtení nebo zápis a dokonce umožňují deklarující třídě zkontrolovat a manipulovat s hodnotou před jejím vrácením nebo přiřazením k poli.

Vlastnost vypadá trochu jako kříženec mezi polem a metodou, protože je deklarována velmi podobně jako pole s viditelností, datovým typem a názvem, ale také má tělo, jako metoda, pro kontrolu chování:

public string Name
{
	get { return _name; }
	set { _name = value; }
}

Všimněte si speciálních klíčových slov get a set. Používají se výhradně pro vlastnosti, aby řídily chování při čtení (get) a zápisu (set) pole. Můžete mít vlastnosti pouze s implementací get NEBO set, abyste vytvořili vlastnosti pouze pro čtení nebo pouze pro zápis, a dokonce můžete řídit viditelnost implementací get nebo set, například pro vytvoření vlastnosti, která může být čtena odkudkoliv (public), ale upravována pouze zevnitř deklarující třídy (private).

Také si všimnete, že odkazuji na pole s názvem _name. To budete muset také deklarovat ve vaší třídě, aby vaše vlastnost mohla být použita. Běžný vzor použití pro pole a vlastnosti bude vypadat takto:

private string _name = "John Doe";

public string Name
{
	get { return _name; }
	set { _name = value; }
}

Nyní můžete vidět, jak pole a vlastnost spolupracují: get metoda vrátí hodnotu pole _name, zatímco set metoda přiřadí předanou hodnotu k poli _name. V metodě set používáme speciální klíčové slovo value, které v této konkrétní situaci odkazuje na hodnotu předanou vlastnosti.

Takže to je v podstatě tak základní, jak to jen jde, a v tomto bodě neděláme nic, co by nemohlo být dosaženo s jednoduchým veřejným polem. Ale později se můžete rozhodnout, že chcete mít větší kontrolu nad tím, jak mohou jiné třídy pracovat s názvem, a protože jste to implementovali jako vlastnost, můžete volně upravovat implementaci bez toho, abyste někoho používajícího vaši třídu rušili. Například vlastnost Name by mohla být upravena takto:

private string _name = "John Doe";

public string Name
{
	get 
	{
		return _name.ToUpper();
	}
	set 
	{
		if(!value.Contains(" "))
			throw new Exception("Please specify both first and last name!");
		_name = value; 
	}
}

Get metoda nyní zajišťuje, že vrácená hodnota je vždy velkými písmeny, bez ohledu na to, ve kterém případě je základní pole (_name). V set metodě jsme přidali několik řádků kódu pro kontrolu, zda předaná hodnota obsahuje mezeru, protože jsme se rozhodli, že jméno by mělo vždy obsahovat jak křestní jméno, tak příjmení - pokud to tak není, je vyhozena výjimka. To je vše velmi hrubé a zjednodušené, ale mělo by ilustrovat plnou úroveň kontroly, kterou získáte při použití vlastností.

Vlastnosti jen pro čtení (read-only)

Většina vlastností, které uvidíte v příkladech tohoto tutoriálu, bude čitelná i zapisovatelná, protože to je nejčastější použití vlastností, ale nemusí to tak být vždy. Především můžete deklarovat vlastnost pouze s get-metodou, takto:

private string _name = "John Doe";

public string Name
{
	get { return _name; }
}

V tomto případě již nemůžete změnit vlastnost "Name" - můžete ji pouze číst a kompilátor vyhodí chybu, pokud se jí pokusíte přiřadit hodnotu. Hodnotu stále můžete změnit zevnitř třídy, protože můžete jednoduše přiřadit novou hodnotu základnímu poli "_name". Dělat to takto ale jakoby popírá jednu z největších výhod vlastností: schopnost vždy kontrolovat, zda může být hodnota přijata. Jak jsme již hovořili, set-metoda je skvělým způsobem, jak provádět validaci hodnoty, ale pokud přiřadíte novou hodnotu poli _name z více míst, protože vlastnost je pouze pro čtení, tuto validaci nezískáte.

Naštěstí pro nás C# nabízí řešení: Můžete na vlastnosti definovat set metodu, ale omezit její viditelnost pomocí klíčového slova private (soukromá) nebo protected (chráněná). To vám poskytne to nejlepší z obou světů, kde můžete stále přiřazovat hodnotu vlastnosti zevnitř třídy (nebo jakékoli odvozené třídy, pokud použijete klíčové slovo protected) a mít ji odpovídajícím způsobem validovanou. Zde je příklad:

private string _name = "John Doe";

public string Name
{
	get { return _name; }

	private set
	{
		if(IsValidName(value))
			this._name = value;
	}
}

public bool IsValidName(string name)
{
	return name.EndsWith("Doe");

}

Rozdíl je jednoduše v klíčovém slovu "private" přímo před slovem "set" a jak bylo zmíněno, můžete jej nahradit například "protected" nebo "internal", v závislosti na vašich potřebách.

Automaticky implementované vlastnosti

V některých případech nepotřebujete veškerou kontrolu nad polem a může se zdát obtížné implementovat jak pole, tak vlastnost s metodami get a set, které nedělají nic jiného, než co jsme viděli v prvním příkladu. Může být lákavé jednoduše deklarovat vaši proměnnou jako veřejné pole, aby se předešlo všem těmto dalším obtížím. Ale nedělejte to! Naštěstí pro nás všechny se Microsoft rozhodl přidat automaticky implementované vlastnosti ve verzi C# 3, což vám ušetří několik řádků kódu. Stačí zvážit rozdíl:

Běžná vlastnost s deklarovaným základním polem:

private string _name;

public string Name
{
	get { return _name; }
	set { _name = value; }
}

Přesně stejné chování, ale s automaticky implementovanou vlastností:

public string Name { get; set; }

Všimněte si, že metody get a set jsou prázdné a že není deklarováno žádné soukromé základní pole - jinými slovy, nyní můžeme dosáhnout přesně stejného chování jako v prvním příkladu, ale s jediným řádkem kódu! Mějte na paměti, že soukromé základní pole bude stále existovat za běhu - bude automaticky implementováno kompilátorem, jak název napovídá. Pokud byste později rozhodli, že potřebujete více kontroly nad touto konkrétní vlastností, můžete ji jednoduše změnit na kombinaci běžného pole/vlastnosti s požadovanou implementací metod get a set.

Všimněte si, že při použití automaticky implementovaných vlastností si stále ponecháváte důležitý mechanismus kontroly z běžných vlastností: Můžete vynechat klíčové slovo set, abyste vytvořili vlastnost pouze pro čtení, například takto:

public string ReadOnlyProperty { get; }

Vlastnosti pouze pro zápis nejsou povoleny při použití automaticky implementovaných vlastností.

Automaticky implementované vlastnosti s výchozími hodnotami

Před verzí C# 6 nebylo možné definovat výchozí hodnotu pro automaticky implementovanou vlastnost - pro to byste potřebovali deklarované základní pole, které by vám umožnilo inicializovat proměnnou s hodnotou:

private string _name = "John Doe";

public string Name
{
	get { return _name; }
	set { _name = value; }
}

Ale ve verzi C# 6 Microsoft konečně přidal možnost inicializovat automaticky implementovanou vlastnost s výchozí hodnotou, takto:

public string Name { get; set; } = "John Doe";

Vlastnosti založené na výrazech

Další funkcí související s vlastnostmi, kterou Microsoft implementoval v C# 6.0 a 7.0, jsou členové založení na výrazech. Jednoduše vám umožní psát jednořádkové výrazy pro vaše vlastnosti a metody - v tomto případě se podívejme, jak ji použít pro vaše get/set metody způsobem, který zabere méně místa a vyžaduje méně psaní:

private string name;
public string Name
{
	get => name;
	set => name = value;
}

Pokud je vaše vlastnost pouze pro čtení, syntaxe může být ještě kratší:

public string Name => "John Doe";

Samozřejmě to funguje i v případě, že potřebujete před vrácením hodnoty něco udělat, jako v tomto případě:

public string Name { get; set; } = "John Doe";

public string FirstName => this.Name.Substring(0, this.Name.IndexOf(" "));

Jak vidíte, to vám umožňuje definovat get metodu, ale bez skutečných klíčových slov get a return, zatímco vás povzbuzuje k tomu, abyste to vše udrželi na jednom řádku namísto několika řádků.

Shrnutí

Vlastnosti dávají vašim třídám větší kontrolu nad tím, jak může být k polím přistupováno a s nimi manipulováno, a měly by být vždy použity, když chcete poskytnout přístup k polím z vnějšku deklarující třídy.


This article has been fully translated into the following languages: Is your preferred language not on the list? Click here to help us translate this article into your language!