Obecný systém typů
Systém běžných typů definuje, jak se typy deklarují, používají a spravují v modulu CLR (Common Language Runtime) a je také důležitou součástí podpory modulu runtime pro integraci mezi jazyky. Systém běžných typů provádí následující funkce:
Vytvoří architekturu, která umožňuje integraci mezi jazyky, bezpečnost typů a vysoce výkonné spouštění kódu.
Poskytuje objektově orientovaný model, který podporuje kompletní implementaci mnoha programovacích jazyků.
Definuje pravidla, která musí jazyky dodržovat, což pomáhá zajistit, aby objekty napsané v různých jazycích mohly vzájemně komunikovat.
Poskytuje knihovnu, která obsahuje primitivní datové typy (například Boolean, ByteChar, , Int32a UInt64) používané při vývoji aplikací.
Typy v .NET
Všechny typy v .NET jsou typy hodnot nebo odkazové typy.
Hodnotové typy jsou datové typy, jejichž objekty jsou reprezentovány skutečnou hodnotou objektu. Pokud je instance typu hodnoty přiřazena proměnné, má tato proměnná čerstvou kopii hodnoty.
Odkazové typy jsou datové typy, jejichž objekty jsou reprezentovány odkazem (podobně jako ukazatel) na skutečnou hodnotu objektu. Pokud je k proměnné přiřazen typ odkazu, odkazuje tato proměnná (odkazuje na) původní hodnotu. Neprovedou se žádné kopie.
Systém běžných typů v .NET podporuje následující pět kategorií typů:
Třídy
Třída je referenční typ, který lze odvodit přímo z jiné třídy a který je odvozen implicitně z System.Object. Třída definuje operace, které může objekt (což je instance třídy) provádět (metody, události nebo vlastnosti) a data, která objekt obsahuje (pole). I když třída obecně zahrnuje definici i implementaci (na rozdíl od rozhraní, která obsahují pouze definici bez implementace), může mít jeden nebo více členů, které nemají žádnou implementaci.
Následující tabulka popisuje některé vlastnosti, které třída může mít. Každý jazyk, který podporuje modul runtime, poskytuje způsob, jak označit, že třída nebo člen třídy má jednu nebo více těchto charakteristik. Jednotlivé programovací jazyky, které cílí na .NET, ale nemusí zpřístupnit všechny tyto charakteristiky.
Charakteristika | Popis |
---|---|
sealed | Určuje, že jiná třída nemůže být odvozena z tohoto typu. |
implements | Označuje, že třída používá jedno nebo více rozhraní poskytováním implementací členů rozhraní. |
abstract | Označuje, že třídu nelze vytvořit instanci. Pokud ho chcete použít, musíte z ní odvodit jinou třídu. |
Dědí | Označuje, že instance třídy lze použít kdekoli, kde je zadaná základní třída. Odvozená třída, která dědí ze základní třídy, může použít implementaci všech veřejných členů poskytovaných základní třídou nebo odvozená třída může přepsat implementaci veřejných členů vlastní implementací. |
exportováno nebo neexportováno | Určuje, zda je třída viditelná mimo sestavení, ve kterém je definována. Tato charakteristika se vztahuje pouze na třídy nejvyšší úrovně, nikoli na vnořené třídy. |
Poznámka:
Třídu lze také vnořit do nadřazené třídy nebo struktury. Vnořené třídy mají také vlastnosti členů. Další informace naleznete v tématu Vnořené typy.
Členy třídy, které nemají žádnou implementaci, nejsou abstraktní členy. Třída, která má jeden nebo více abstraktních členů je sám abstraktní; nelze vytvořit nové instance. Některé jazyky, které cílí na modul runtime, umožňují označit třídu jako abstraktní, i když žádný z jejích členů není abstraktní. Abstraktní třídu můžete použít, pokud chcete zapouzdření základní sady funkcí, které odvozené třídy mohou v případě potřeby dědit nebo přepsat. Třídy, které nejsou abstraktní, se označují jako konkrétní třídy.
Třída může implementovat libovolný počet rozhraní, ale může dědit pouze z jedné základní třídy kromě System.Object, ze kterých všechny třídy dědí implicitně. Všechny třídy musí mít alespoň jeden konstruktor, který inicializuje nové instance třídy. Pokud konstruktor explicitně nedefinujete, většina kompilátorů automaticky poskytne konstruktor bez parametrů.
Struktury
Struktura je typ hodnoty, který je odvozen implicitně z System.ValueType, který je následně odvozen z System.Object. Struktura je užitečná pro reprezentaci hodnot, jejichž požadavky na paměť jsou malé, a pro předávání hodnot jako parametrů podle hodnot metodám, které mají parametry silného typu. V .NET jsou definovány všechny primitivní datové typy (Boolean, Byte, Char, DateTime, Decimal, Double, Int16, SByteSingleInt64UInt16Int32UInt32, a UInt64) jako struktury.
Podobně jako třídy definují struktury jak data (pole struktury), tak operace, které lze na těchto datech provádět (metody struktury). To znamená, že můžete volat metody u struktur, včetně virtuálních metod definovaných ve System.Object System.ValueType třídách a všech metod definovaných na samotném typu hodnoty. Jinými slovy, struktury mohou mít pole, vlastnosti a události, stejně jako statické a nestatické metody. Můžete vytvářet instance struktur, předávat je jako parametry, ukládat je jako místní proměnné nebo je ukládat do pole jiného typu hodnoty nebo referenčního typu. Struktury mohou také implementovat rozhraní.
Typy hodnot se také liší od tříd v několika ohledech. Za prvé, i když implicitně dědí z System.ValueType, nemohou přímo dědit z jakéhokoli typu. Podobně jsou všechny typy hodnot zapečetěné, což znamená, že z nich nelze odvodit žádný jiný typ. Nevyžadují také konstruktory.
Modul CLR (Common Language Runtime) pro každý typ hodnoty poskytuje odpovídající typ boxu, což je třída, která má stejný stav a chování jako typ hodnoty. Instance typu hodnoty je boxována při předání metodě, která přijímá parametr typu System.Object. Je unboxed (tj. převeden z instance třídy zpět na instanci typu hodnoty) při návratu ovládacího prvku z volání metody, který přijímá typ hodnoty jako parametr by-reference. Některé jazyky vyžadují, abyste použili speciální syntaxi, pokud je vyžadován typ rámečku; ostatní automaticky použijí typ pole, pokud je to potřeba. Když definujete typ hodnoty, definujete boxovaný i unboxed typ.
Výčty
Výčet je typ hodnoty, který dědí přímo z System.Enum a který poskytuje alternativní názvy hodnot základního primitivního typu. Typ výčtu má název, základní typ, který musí být jedním z předdefinovaných nebo nepodepsaných celočísných typů (například Byte, Int32nebo UInt64) a sady polí. Pole jsou statická literálová pole, z nichž každá představuje konstantu. Stejnou hodnotu lze přiřadit více polím. Pokud k tomu dojde, musíte jednu z hodnot označit jako primární hodnotu výčtu pro reflexi a převod řetězce.
K výčtu můžete přiřadit hodnotu základního typu a naopak (modul runtime nevyžaduje žádné přetypování). Můžete vytvořit instanci výčtu a volat metody System.Enum, stejně jako všechny metody definované v podkladovém typu výčtu. Některé jazyky ale nemusí umožnit předání výčtu jako parametru, pokud je požadována instance základního typu (nebo naopak).
Následující další omezení se vztahují na výčty:
Nemůžou definovat vlastní metody.
Nemůžou implementovat rozhraní.
Nemůžou definovat vlastnosti ani události.
Nemohou být obecné, pokud nejsou obecné pouze proto, že jsou vnořené do obecného typu. To znamená, že výčet nemůže mít vlastní parametry typu.
Poznámka:
Vnořené typy (včetně výčtů) vytvořené pomocí jazyka Visual Basic, C# a C++ obsahují parametry typu všech uzavřených obecných typů, a proto jsou obecné i v případě, že nemají vlastní parametry typu. Další informace naleznete v tématu "Vnořené typy" v referenčním Type.MakeGenericType tématu.
Atribut FlagsAttribute označuje zvláštní druh výčtu, který se nazývá bitové pole. Samotný modul runtime nerozlišuje mezi tradičními výčty a bitovými poli, ale váš jazyk to může udělat. Pokud je toto rozlišení provedeno, bitové operátory lze použít u bitových polí, ale ne pro výčty, ke generování nepojmenovaných hodnot. Výčty se obvykle používají pro seznamy jedinečných prvků, jako jsou dny v týdnu, názvy zemí nebo oblastí atd. Bitová pole se obvykle používají pro seznamy vlastností nebo množství, ke kterým může dojít v kombinaci, například Red And Big And Fast
.
Následující příklad ukazuje, jak používat bitová pole i tradiční výčty.
using System;
using System.Collections.Generic;
// A traditional enumeration of some root vegetables.
public enum SomeRootVegetables
{
HorseRadish,
Radish,
Turnip
}
// A bit field or flag enumeration of harvesting seasons.
[Flags]
public enum Seasons
{
None = 0,
Summer = 1,
Autumn = 2,
Winter = 4,
Spring = 8,
All = Summer | Autumn | Winter | Spring
}
public class Example
{
public static void Main()
{
// Hash table of when vegetables are available.
Dictionary<SomeRootVegetables, Seasons> AvailableIn = new Dictionary<SomeRootVegetables, Seasons>();
AvailableIn[SomeRootVegetables.HorseRadish] = Seasons.All;
AvailableIn[SomeRootVegetables.Radish] = Seasons.Spring;
AvailableIn[SomeRootVegetables.Turnip] = Seasons.Spring |
Seasons.Autumn;
// Array of the seasons, using the enumeration.
Seasons[] theSeasons = new Seasons[] { Seasons.Summer, Seasons.Autumn,
Seasons.Winter, Seasons.Spring };
// Print information of what vegetables are available each season.
foreach (Seasons season in theSeasons)
{
Console.Write(String.Format(
"The following root vegetables are harvested in {0}:\n",
season.ToString("G")));
foreach (KeyValuePair<SomeRootVegetables, Seasons> item in AvailableIn)
{
// A bitwise comparison.
if (((Seasons)item.Value & season) > 0)
Console.Write(String.Format(" {0:G}\n",
(SomeRootVegetables)item.Key));
}
}
}
}
// The example displays the following output:
// The following root vegetables are harvested in Summer:
// HorseRadish
// The following root vegetables are harvested in Autumn:
// Turnip
// HorseRadish
// The following root vegetables are harvested in Winter:
// HorseRadish
// The following root vegetables are harvested in Spring:
// Turnip
// Radish
// HorseRadish
Imports System.Collections.Generic
' A traditional enumeration of some root vegetables.
Public Enum SomeRootVegetables
HorseRadish
Radish
Turnip
End Enum
' A bit field or flag enumeration of harvesting seasons.
<Flags()> Public Enum Seasons
None = 0
Summer = 1
Autumn = 2
Winter = 4
Spring = 8
All = Summer Or Autumn Or Winter Or Spring
End Enum
' Entry point.
Public Class Example
Public Shared Sub Main()
' Hash table of when vegetables are available.
Dim AvailableIn As New Dictionary(Of SomeRootVegetables, Seasons)()
AvailableIn(SomeRootVegetables.HorseRadish) = Seasons.All
AvailableIn(SomeRootVegetables.Radish) = Seasons.Spring
AvailableIn(SomeRootVegetables.Turnip) = Seasons.Spring Or _
Seasons.Autumn
' Array of the seasons, using the enumeration.
Dim theSeasons() As Seasons = {Seasons.Summer, Seasons.Autumn, _
Seasons.Winter, Seasons.Spring}
' Print information of what vegetables are available each season.
For Each season As Seasons In theSeasons
Console.WriteLine(String.Format( _
"The following root vegetables are harvested in {0}:", _
season.ToString("G")))
For Each item As KeyValuePair(Of SomeRootVegetables, Seasons) In AvailableIn
' A bitwise comparison.
If (CType(item.Value, Seasons) And season) > 0 Then
Console.WriteLine(" " + _
CType(item.Key, SomeRootVegetables).ToString("G"))
End If
Next
Next
End Sub
End Class
' The example displays the following output:
' The following root vegetables are harvested in Summer:
' HorseRadish
' The following root vegetables are harvested in Autumn:
' Turnip
' HorseRadish
' The following root vegetables are harvested in Winter:
' HorseRadish
' The following root vegetables are harvested in Spring:
' Turnip
' Radish
' HorseRadish
Rozhraní
Rozhraní definuje kontrakt, který určuje relaci "může provést" nebo "má" relaci. Rozhraní se často používají k implementaci funkcí, jako je porovnávání a řazení ( IComparable rozhraní IComparable<T> ), testování rovnosti ( IEquatable<T> rozhraní) nebo výčet položek v kolekci (rozhraní IEnumerable a IEnumerable<T> rozhraní). Rozhraní mohou mít vlastnosti, metody a události, z nichž všechny jsou abstraktní členy; to znamená, že i když rozhraní definuje členy a jejich podpisy, ponechá ho na typ, který implementuje rozhraní pro definování funkčnosti každého člena rozhraní. To znamená, že každá třída nebo struktura, která implementuje rozhraní, musí poskytovat definice pro abstraktní členy deklarované v rozhraní. Rozhraní může vyžadovat jakoukoli implementaci třídy nebo struktury k implementaci jednoho nebo více dalších rozhraní.
Pro rozhraní platí následující omezení:
- Rozhraní lze deklarovat s jakýmkoli usnadněním, ale všichni členové rozhraní musí mít veřejnou přístupnost.
- Rozhraní nemohou definovat konstruktory.
- Rozhraní nemohou definovat pole.
- Rozhraní mohou definovat pouze členy instance. Nemůžou definovat statické členy.
Každý jazyk musí poskytovat pravidla pro mapování implementace na rozhraní, které vyžaduje člen, protože více než jedno rozhraní může deklarovat člen se stejným podpisem a tito členové mohou mít samostatné implementace.
Delegáti
Delegáti jsou odkazové typy, které slouží k účelu podobnému ukazateli funkce v jazyce C++. Používají se pro obslužné rutiny událostí a funkce zpětného volání v .NET. Na rozdíl od ukazatelů funkce jsou delegáti zabezpečení, ověřitelná a typová bezpečnost. Typ delegáta může představovat jakoukoli metodu instance nebo statickou metodu, která má kompatibilní podpis.
Parametr delegáta je kompatibilní s odpovídajícím parametrem metody, pokud je typ parametru delegáta více omezující než typ parametru metody, protože to zaručuje, že argument předaný delegátu lze metodě bezpečně předat.
Podobně návratový typ delegáta je kompatibilní s návratovým typem metody, pokud je návratový typ metody více omezující než návratový typ delegáta, protože to zaručuje, že návratovou hodnotu metody lze bezpečně přetypovat na návratový typ delegáta.
Například delegát, který má parametr typu IEnumerable a návratový Object typ, může představovat metodu, která má parametr typu Object a návratovou hodnotu typu IEnumerable. Další informace a ukázkový kód naleznete v tématu Delegate.CreateDelegate(Type, Object, MethodInfo).
Delegát je vázán na metodu, která představuje. Kromě vázání na metodu může být delegát vázán na objekt. Objekt představuje první parametr metody a je předán metodě při každém vyvolání delegáta. Pokud je metoda instance metoda, vázané objekt je předán jako implicitní this
parametr (Me
v jazyce Visual Basic); pokud je metoda statická, objekt se předá jako první formální parametr metody a podpis delegáta musí odpovídat zbývajícím parametrům. Další informace a ukázkový kód naleznete v tématu System.Delegate.
Všichni delegáti dědí z System.MulticastDelegate, který dědí z System.Delegate. Jazyky C#, Visual Basic a C++ neumožňují dědičnost z těchto typů. Místo toho poskytují klíčová slova pro deklarování delegátů.
Vzhledem k tomu, že delegáti dědí z MulticastDelegate, má delegát seznam vyvolání, což je seznam metod, které delegát představuje a které jsou spuštěny při vyvolání delegáta. Všechny metody v seznamu obdrží argumenty zadané při vyvolání delegáta.
Poznámka:
Návratová hodnota není definována pro delegáta, který má v seznamu volání více než jednu metodu, i když má delegát návratový typ.
V mnoha případech, například pomocí metod zpětného volání, delegát představuje pouze jednu metodu a jediné akce, které musíte provést, vytváří delegáta a vyvolává ho.
Pro delegáty, které představují více metod, .NET poskytuje metody Delegate tříd a MulticastDelegate delegátů pro podporu operací, jako je přidání metody do seznamu vyvolání delegáta ( Delegate.Combine metoda), odebrání metody ( Delegate.Remove metoda) a získání seznamu vyvolání ( Delegate.GetInvocationList metoda).
Poznámka:
Tyto metody není nutné používat pro delegáty obslužné rutiny událostí v jazyce C#, C++ a Visual Basic, protože tyto jazyky poskytují syntaxi pro přidávání a odebírání obslužných rutin událostí.
Definice typů
Definice typu zahrnuje následující:
- Všechny atributy definované v typu.
- Přístupnost (viditelnost) typu
- Název typu.
- Základní typ typu.
- Všechna rozhraní implementovaná typem.
- Definice pro jednotlivé členy typu.
Atributy
Atributy poskytují další uživatelsky definovaná metadata. Nejčastěji se používají k ukládání dalších informací o typu v jeho sestavení nebo ke změně chování člena typu v prostředí návrhu nebo za běhu.
Atributy jsou samy třídy, které dědí z System.Attribute. Jazyky, které podporují použití atributů, mají vlastní syntaxi pro použití atributů u elementu jazyka. Atributy lze použít na téměř jakýkoli prvek jazyka; konkrétní prvky, na které lze atribut použít, jsou definovány tím AttributeUsageAttribute , který je použit na danou třídu atributu.
Usnadnění přístupu typu
Všechny typy mají modifikátor, který řídí jejich přístupnost z jiných typů. Následující tabulka popisuje dostupnost typů podporovanou modulem runtime.
Usnadnění | Popis |
---|---|
public | Typ je přístupný všemi sestaveními. |
sestavení | Typ je přístupný pouze z jeho sestavení. |
Přístupnost vnořeného typu závisí na jeho doméně přístupnosti, která je určena deklarovanou přístupností člena i doménou přístupnosti bezprostředně obsahujícího typu. Doména přístupnosti vnořeného typu však nemůže překročit doménu obsahujícího typu.
Doména přístupnosti vnořeného člena M
deklarovaného v typu T
v rámci programu P
je definována následujícím způsobem (to znamená, že M
samotný typ může být):
Pokud je deklarovaná přístupnost
M
, doménaM
přístupnosti je doména přístupnosti doményT
.public
Pokud je deklarovaná přístupnost
M
protected internal
, doménaM
přístupnosti je průnikem doményT
přístupnosti s textemP
programu a textem programu libovolného typu odvozeného zT
deklarované mimoP
.Pokud je deklarovaná přístupnost
M
, doménaM
přístupnosti je průnikem doményT
přístupnosti s textemT
programu a libovolným typem odvozeným zT
.protected
Pokud je deklarovaná přístupnost
M
internal
, doménaM
přístupnosti je průnikem doményT
přístupnosti s textemP
programu .Pokud je deklarovaná přístupnost
M
private
, doménaM
přístupnosti je textT
programu .
Názvy typů
Systém běžných typů omezuje pouze dvě omezení názvů:
- Všechny názvy jsou kódovány jako řetězce znaků Unicode (16bitové).
- Názvy nesmí mít vloženou (16bitovou) hodnotu 0x0000.
Většina jazyků však omezuje názvy typů. Všechna porovnání se provádějí na bajtovém základě, a proto rozlišují malá a velká písmena a národní prostředí nezávislá.
I když typ může odkazovat na typy z jiných modulů a sestavení, musí být typ plně definován v rámci jednoho modulu .NET. (V závislosti na podpoře kompilátoru je však možné ji rozdělit do několika souborů zdrojového kódu.) Názvy typů musí být jedinečné pouze v rámci oboru názvů. Chcete-li plně identifikovat typ, musí být název typu kvalifikovaný oborem názvů, který obsahuje implementaci typu.
Základní typy a rozhraní
Typ může dědit hodnoty a chování z jiného typu. Systém běžných typů neumožňuje dědit typy z více než jednoho základního typu.
Typ může implementovat libovolný počet rozhraní. Chcete-li implementovat rozhraní, musí typ implementovat všechny virtuální členy tohoto rozhraní. Virtuální metodu lze implementovat odvozeným typem a lze ji vyvolat staticky nebo dynamicky.
Členy typu
Modul runtime umožňuje definovat členy vašeho typu, které určují chování a stav typu. Mezi členy typu patří:
Pole
Pole popisuje a obsahuje část stavu typu. Pole můžou být libovolného typu podporovaného modulem runtime. Nejčastěji jsou pole buď private
nebo protected
, aby byla přístupná pouze z třídy nebo z odvozené třídy. Pokud lze hodnotu pole změnit z vnějšího typu, obvykle se používá přístupové objekty sady vlastností. Veřejně vystavená pole jsou obvykle jen pro čtení a můžou mít dva typy:
- Konstanty, jejichž hodnota je přiřazena v době návrhu. Jedná se o statické členy třídy, i když nejsou definovány pomocí klíčového
static
slova (Shared
v jazyce Visual Basic). - Proměnné jen pro čtení, jejichž hodnoty lze přiřadit v konstruktoru třídy.
Následující příklad ukazuje tato dvě použití polí jen pro čtení.
using System;
public class Constants
{
public const double Pi = 3.1416;
public readonly DateTime BirthDate;
public Constants(DateTime birthDate)
{
this.BirthDate = birthDate;
}
}
public class Example
{
public static void Main()
{
Constants con = new Constants(new DateTime(1974, 8, 18));
Console.Write(Constants.Pi + "\n");
Console.Write(con.BirthDate.ToString("d") + "\n");
}
}
// The example displays the following output if run on a system whose current
// culture is en-US:
// 3.1416
// 8/18/1974
Public Class Constants
Public Const Pi As Double = 3.1416
Public ReadOnly BirthDate As Date
Public Sub New(birthDate As Date)
Me.BirthDate = birthDate
End Sub
End Class
Public Module Example
Public Sub Main()
Dim con As New Constants(#8/18/1974#)
Console.WriteLine(Constants.Pi.ToString())
Console.WriteLine(con.BirthDate.ToString("d"))
End Sub
End Module
' The example displays the following output if run on a system whose current
' culture is en-US:
' 3.1416
' 8/18/1974
Vlastnosti
Vlastnost pojmenuje hodnotu nebo stav typu a definuje metody pro získání nebo nastavení hodnoty vlastnosti. Vlastnosti mohou být primitivní typy, kolekce primitivních typů, uživatelem definované typy nebo kolekce uživatelsky definovaných typů. Vlastnosti se často používají k zachování veřejného rozhraní typu nezávisle na skutečné reprezentaci typu. To umožňuje vlastnostem odrážet hodnoty, které nejsou přímo uloženy ve třídě (například když vlastnost vrací vypočítanou hodnotu) nebo provést ověření před přiřazením hodnot k privátním polím. Následující příklad znázorňuje druhý vzor.
using System;
public class Person
{
private int m_Age;
public int Age
{
get { return m_Age; }
set {
if (value < 0 || value > 125)
{
throw new ArgumentOutOfRangeException("The value of the Age property must be between 0 and 125.");
}
else
{
m_Age = value;
}
}
}
}
Public Class Person
Private m_Age As Integer
Public Property Age As Integer
Get
Return m_Age
End Get
Set
If value < 0 Or value > 125 Then
Throw New ArgumentOutOfRangeException("The value of the Age property must be between 0 and 125.")
Else
m_Age = value
End If
End Set
End Property
End Class
Kromě zahrnutí samotné vlastnosti zahrnuje společný zprostředkující jazyk (CIL) pro typ, který obsahuje čitelné vlastnosti, zahrnuje metodu get_
propertyname a CIL pro typ, který obsahuje zapisovatelnou vlastnost obsahuje metoduset_
propertyname.
Metody
Metoda popisuje operace, které jsou k dispozici u typu. Podpis metody určuje povolené typy všech jeho parametrů a jeho návratové hodnoty.
I když většina metod definuje přesný počet parametrů požadovaných pro volání metody, některé metody podporují proměnný počet parametrů. Konečný deklarovaný parametr těchto metod je označen atributem ParamArrayAttribute . Kompilátory jazyka obvykle poskytují klíčové slovo, například params
v jazyce C# a ParamArray
v jazyce Visual Basic, které explicitně využívá ParamArrayAttribute nepotřebné.
Konstruktory
Konstruktor je speciální druh metody, která vytváří nové instance třídy nebo struktury. Stejně jako jakákoli jiná metoda může konstruktor obsahovat parametry; konstruktory však nemají žádnou návratnou hodnotu (to znamená, že vrátí void
).
Pokud zdrojový kód třídy explicitně nedefinuje konstruktor, kompilátor obsahuje konstruktor bez parametrů. Pokud však zdrojový kód pro třídu definuje pouze parametrizované konstruktory, kompilátory jazyka Visual Basic a C# negenerují konstruktor bez parametrů.
Pokud zdrojový kód struktury definuje konstruktory, musí být parametrizován; Struktura nemůže definovat konstruktor bez parametrů a kompilátory negenerují konstruktory bez parametrů pro struktury nebo jiné typy hodnot. Všechny typy hodnot mají implicitní konstruktor bez parametrů. Tento konstruktor je implementován modulem CLR (Common Language Runtime) a inicializuje všechna pole struktury na výchozí hodnoty.
Události
Událost definuje incident, na který lze reagovat, a definuje metody pro přihlášení k odběru, zrušení odběru a vyvolání události. Události se často používají k informování jiných typů změn stavu. Další informace naleznete v tématu Události.
Vnořené typy
Vnořený typ je typ, který je členem jiného typu. Vnořené typy by měly být úzce svázány s jejich typem obsahujícím a nesmí být užitečné jako typ pro obecné účely. Vnořené typy jsou užitečné, když deklarující typ používá a vytváří instance vnořeného typu a použití vnořeného typu není vystaveno ve veřejných členech.
Vnořené typy jsou pro některé vývojáře matoucí a neměly by být veřejně viditelné, pokud neexistuje přesvědčivý důvod viditelnosti. V dobře navržené knihovně by vývojáři měli zřídka používat vnořené typy k vytváření instancí objektů nebo deklarování proměnných.
Charakteristiky členů typu
Společný systém typů umožňuje členům typů různé charakteristiky; jazyky však nejsou nutné pro podporu všech těchto charakteristik. Následující tabulka popisuje charakteristiky členů.
Charakteristika | Může platit pro | Popis |
---|---|---|
abstract | Metody, vlastnosti a události | Typ neposkytuje implementaci metody. Typy, které dědí nebo implementují abstraktní metody, musí poskytnout implementaci metody. Jedinou výjimkou je, když je odvozený typ sám abstraktním typem. Všechny abstraktní metody jsou virtuální. |
soukromá, rodina, sestavení, rodina a sestavení, rodina nebo sestavení nebo veřejná | Všechny | Definuje přístupnost člena: private Přístupné pouze ze stejného typu jako člen nebo vnořený typ. family Přístupné ze stejného typu jako člen a z odvozených typů, které z něj dědí. sestavení Přístupné pouze v sestavení, ve kterém je typ definován. rodina a sestavení Přístupné pouze z typů, které mají nárok na přístup k rodině i sestavení. rodina nebo sestavení Přístupné pouze z typů, které mají nárok na přístup k rodině nebo sestavení. public Přístupné z libovolného typu. |
finální | Metody, vlastnosti a události | Virtuální metodu nelze přepsat v odvozeného typu. |
inicializace pouze | Pole | Hodnotu lze inicializovat pouze a nelze ji zapsat po inicializaci. |
instance | Pole, metody, vlastnosti a události | Pokud není člen označený jako static (C# a C++), Shared (Visual Basic), virtual (C# a C++) nebo Overridable (Visual Basic), je členem instance (neexistuje žádné klíčové slovo instance). V paměti bude tolik kopií takových členů, kolik jich používá. |
literal | Pole | Hodnota přiřazená k poli je pevná hodnota, známá v době kompilace, integrovaného typu hodnoty. Literálová pole se někdy označují jako konstanty. |
newslot nebo override | Všechny | Definuje, jak člen komunikuje s zděděnými členy, kteří mají stejný podpis: newslot Skryje zděděné členy se stejným podpisem. override Nahradí definici zděděné virtuální metody. Výchozí hodnota je newslot. |
static | Pole, metody, vlastnosti a události | Člen patří k typu, na který je definován, nikoli ke konkrétní instanci typu; člen existuje i v případě, že instance typu není vytvořena a je sdílena mezi všemi instancemi typu. |
virtual | Metody, vlastnosti a události | Metodu lze implementovat odvozeným typem a lze ji vyvolat staticky nebo dynamicky. Pokud se používá dynamické vyvolání, typ instance, která provádí volání za běhu (místo typu známého v době kompilace) určuje, která implementace metody je volána. Pokud chcete virtuální metodu vyvolat staticky, může být nutné přetypovat proměnnou na typ, který používá požadovanou verzi metody. |
Přetížení
Každý člen typu má jedinečný podpis. Podpisy metody se skládají z názvu metody a seznamu parametrů (pořadí a typy argumentů metody). V rámci typu lze definovat více metod se stejným názvem, pokud se jejich podpisy liší. Pokud jsou definovány dvě nebo více metod se stejným názvem, říká se, že je přetížená. Například v System.Char, IsDigit metoda je přetížena. Jedna metoda přebírá Char. Druhá metoda vezme a String Int32.
Poznámka:
Návratový typ není považován za součást podpisu metody. To znamená, že metody nelze přetížit, pokud se liší pouze návratový typ.
Dědění, přepsání a skrytí členů
Odvozený typ dědí všechny členy základního typu; to znamená, že tyto členy jsou definovány a k dispozici pro odvozený typ. Chování nebo vlastnosti zděděných členů lze upravit dvěma způsoby:
Odvozený typ může skrýt zděděný člen definováním nového člena se stejným podpisem. To může být provedeno, aby dříve veřejný člen soukromý nebo definovat nové chování pro zděděnou metodu, která je označena jako
sealed
.Odvozený typ může přepsat zděděnou virtuální metodu. Metoda přepsání poskytuje novou definici metody, která bude vyvolána na základě typu hodnoty za běhu, a nikoli typu proměnné známé v době kompilace. Metoda může přepsat virtuální metodu pouze v případě, že virtuální metoda není označena jako
sealed
a nová metoda je alespoň tak přístupná jako virtuální metoda.