Sdílet prostřednictvím


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éna M přístupnosti je doména přístupnosti domény T.public

  • Pokud je deklarovaná přístupnost M protected internal, doména M přístupnosti je průnikem domény T přístupnosti s textem P programu a textem programu libovolného typu odvozeného z T deklarované mimo P.

  • Pokud je deklarovaná přístupnost M , doména M přístupnosti je průnikem domény T přístupnosti s textem T programu a libovolným typem odvozeným z T.protected

  • Pokud je deklarovaná přístupnost M internal, doména M přístupnosti je průnikem domény T přístupnosti s textem Pprogramu .

  • Pokud je deklarovaná přístupnost M private, doména M přístupnosti je text Tprogramu .

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.

Viz také