ÚvodIntroduction

C#(vyslovit "viz Sharp") je jednoduchý, moderní, objektově orientovaný programovací jazyk, který je typově bezpečný.C# (pronounced "See Sharp") is a simple, modern, object-oriented, and type-safe programming language. C#má své kořeny v řadě jazyků C a bude se okamžitě seznámit s programátory v jazyce C++c, a Java.C# has its roots in the C family of languages and will be immediately familiar to C, C++, and Java programmers. C#je standardizovaná ECMA mezinárodními jako standard ECMA-334 a normou ISO/IEC jako standard iso/IEC 23270 .C# is standardized by ECMA International as the ECMA-334 standard and by ISO/IEC as the ISO/IEC 23270 standard. C# Kompilátor od microsoftu pro .NET Framework je vyhovující implementaci obou těchto standardů.Microsoft's C# compiler for the .NET Framework is a conforming implementation of both of these standards.

C#je objektově orientovaný jazyk, ale C# dále zahrnuje podporu pro programování orientované na komponenty .C# is an object-oriented language, but C# further includes support for component-oriented programming. Moderní návrh softwaru se stále spoléhá na softwarové komponenty ve formě integrovaných a samoobslužných balíčků funkcí.Contemporary software design increasingly relies on software components in the form of self-contained and self-describing packages of functionality. Klíč k takovým součástem je, že prezentují programovací model s vlastnostmi, metodami a událostmi. mají atributy, které poskytují deklarativní informace o komponentě. a obsahují vlastní dokumentaci.Key to such components is that they present a programming model with properties, methods, and events; they have attributes that provide declarative information about the component; and they incorporate their own documentation. C#poskytuje jazykové konstrukce, které přímo podporují tyto koncepce, a C# vytváří tak velmi přirozený jazyk pro vytváření a používání softwarových komponent.C# provides language constructs to directly support these concepts, making C# a very natural language in which to create and use software components.

Několik C# funkcí pomáhá při konstrukci robustních a odolných aplikací: Uvolňování paměti automaticky uvolňuje paměť obsazené nepoužívanými objekty; zpracování výjimek poskytuje strukturovaný a rozšiřitelný přístup k detekci a obnovení chyb. a typově bezpečný návrh tohoto jazyka znemožňuje čtení z neinicializovaných proměnných, pro indexaci polí nad rámec jejich hranic nebo pro provedení nezaškrtnutých přetypování typu.Several C# features aid in the construction of robust and durable applications: Garbage collection automatically reclaims memory occupied by unused objects; exception handling provides a structured and extensible approach to error detection and recovery; and the type-safe design of the language makes it impossible to read from uninitialized variables, to index arrays beyond their bounds, or to perform unchecked type casts.

C#má jednotný systém typů.C# has a unified type system. Všechny C# typy, včetně primitivních typů int , jako jsou a double, dědí z jednoho object kořenového typu.All C# types, including primitive types such as int and double, inherit from a single root object type. Všechny typy tedy sdílí sadu běžných operací a hodnoty libovolného typu mohou být uloženy, přepravovány a provozovány konzistentním způsobem.Thus, all types share a set of common operations, and values of any type can be stored, transported, and operated upon in a consistent manner. Kromě toho C# podporuje uživatelsky definované typy odkazů i typy hodnot, což umožňuje dynamické přidělování objektů a také vložené úložiště lehkých struktur.Furthermore, C# supports both user-defined reference types and value types, allowing dynamic allocation of objects as well as in-line storage of lightweight structures.

Aby bylo zajištěno, že se programy a knihovny můžou v průběhu času vyvíjejí kompatibilním způsobem, je mnohem zdůrazněno, že C# se v návrhu používá Správa verzí C#.To ensure that C# programs and libraries can evolve over time in a compatible manner, much emphasis has been placed on versioning in C#'s design. Řada programovacích jazyků platíte jenom malým pozornostům tohoto problému. v důsledku toho jsou programy napsané v těchto jazycích častěji využívány, pokud jsou zavedeny novější verze závislých knihoven.Many programming languages pay little attention to this issue, and, as a result, programs written in those languages break more often than necessary when newer versions of dependent libraries are introduced. C#Aspekty návrhu, které byly přímo ovlivněny aspekty správy verzí, zahrnují samostatné virtual a override modifikátory, pravidla pro řešení přetížení metod a podporu explicitních deklarací členů rozhraní.Aspects of C#'s design that were directly influenced by versioning considerations include the separate virtual and override modifiers, the rules for method overload resolution, and support for explicit interface member declarations.

Zbytek této kapitoly popisuje základní funkce C# jazyka.The rest of this chapter describes the essential features of the C# language. I když později kapitoly popisují pravidla a výjimky v detailním a někdy matematickém způsobu, tato kapitola usiluje o přehlednost a zkrácení na úkor úplnosti.Although later chapters describe rules and exceptions in a detail-oriented and sometimes mathematical manner, this chapter strives for clarity and brevity at the expense of completeness. Záměrem je poskytnout čtenářům Úvod k jazyku, který usnadní psaní dřívějších programů a čtení dalších kapitol.The intent is to provide the reader with an introduction to the language that will facilitate the writing of early programs and the reading of later chapters.

Hello WorldHello world

Program "Hello, World" se tradičně používá k zavedení programovacího jazyka.The "Hello, World" program is traditionally used to introduce a programming language. Tady je C#:Here it is in C#:

using System;

class Hello
{
    static void Main() {
        Console.WriteLine("Hello, World");
    }
}

C#zdrojové soubory mají obvykle příponu .cssouboru.C# source files typically have the file extension .cs. Za předpokladu, že program "Hello, World" je uložen hello.csv souboru, program může být zkompilován s kompilátorem společnosti Microsoft C# pomocí příkazového řádkuAssuming that the "Hello, World" program is stored in the file hello.cs, the program can be compiled with the Microsoft C# compiler using the command line

csc hello.cs

který vytváří spustitelné sestavení s názvem hello.exe.which produces an executable assembly named hello.exe. Výstup vytvořený touto aplikací při spuštění jeThe output produced by this application when it is run is

Hello, World

Program "Hello, World" začíná using direktivou, která odkazuje na System obor názvů.The "Hello, World" program starts with a using directive that references the System namespace. Obory názvů poskytují hierarchické prostředky pro C# uspořádání programů a knihoven.Namespaces provide a hierarchical means of organizing C# programs and libraries. Obory názvů obsahují System typy a jiné obory názvů, například obor názvů obsahuje počet typů, jako je Console například třída odkazovaná v programu, a řadu IO dalších oborů názvů, například a Collections.Namespaces contain types and other namespaces—for example, the System namespace contains a number of types, such as the Console class referenced in the program, and a number of other namespaces, such as IO and Collections. using Direktiva, která odkazuje na daný obor názvů, umožňuje nekvalifikované použití typů, které jsou členy tohoto oboru názvů.A using directive that references a given namespace enables unqualified use of the types that are members of that namespace. Z using důvodu direktivy může program použít Console.WriteLine jako zkrácený pro System.Console.WriteLine.Because of the using directive, the program can use Console.WriteLine as shorthand for System.Console.WriteLine.

Třída deklarovaná programem "Hello, World" má jednoho člena, metodu s názvem Main. HelloThe Hello class declared by the "Hello, World" program has a single member, the method named Main. Metoda je deklarována static s modifikátorem. MainThe Main method is declared with the static modifier. I když metody instance mohou odkazovat na konkrétní ohraničující objekt instance pomocí klíčového thisslova, statické metody pracují bez odkazů na konkrétní objekt.While instance methods can reference a particular enclosing object instance using the keyword this, static methods operate without reference to a particular object. Podle konvence, statická metoda s Main názvem slouží jako vstupní bod programu.By convention, a static method named Main serves as the entry point of a program.

Výstup programu je vytvořen WriteLine metodou Console třídy v System oboru názvů.The output of the program is produced by the WriteLine method of the Console class in the System namespace. Tato třída je poskytována knihovnami tříd .NET Framework, které jsou ve výchozím nastavení automaticky odkazovány kompilátorem společnosti C# Microsoft.This class is provided by the .NET Framework class libraries, which, by default, are automatically referenced by the Microsoft C# compiler. Všimněte si C# , že sám nemá samostatnou běhovou knihovnu.Note that C# itself does not have a separate runtime library. Místo toho je .NET Framework běhová knihovna C#.Instead, the .NET Framework is the runtime library of C#.

Struktura programuProgram structure

Klíčovou organizační koncepcí v C# nástroji jsou programy, obory názvů, typy, členya sestavení.The key organizational concepts in C# are programs, namespaces, types, members, and assemblies. C#programy se skládají z jednoho nebo více zdrojových souborů.C# programs consist of one or more source files. Programy deklarují typy, které obsahují členy a mohou být uspořádány do oborů názvů.Programs declare types, which contain members and can be organized into namespaces. Příklady typů jsou třídy a rozhraní.Classes and interfaces are examples of types. Příklady členů jsou pole, metody, vlastnosti a události.Fields, methods, properties, and events are examples of members. Když C# jsou programy kompilovány, jsou fyzicky zabaleny do sestavení.When C# programs are compiled, they are physically packaged into assemblies. Sestavení .exe mají obvykle příponu souboru nebo .dllv závislosti na tom, zda implementují aplikace nebo knihovny.Assemblies typically have the file extension .exe or .dll, depending on whether they implement applications or libraries.

PříkladThe example

using System;

namespace Acme.Collections
{
    public class Stack
    {
        Entry top;

        public void Push(object data) {
            top = new Entry(top, data);
        }

        public object Pop() {
            if (top == null) throw new InvalidOperationException();
            object result = top.data;
            top = top.next;
            return result;
        }

        class Entry
        {
            public Entry next;
            public object data;
    
            public Entry(Entry next, object data) {
                this.next = next;
                this.data = data;
            }
        }
    }
}

deklaruje třídu s názvem Stack v oboru názvů s názvem. Acme.Collectionsdeclares a class named Stack in a namespace called Acme.Collections. Plně kvalifikovaný název této třídy je Acme.Collections.Stack.The fully qualified name of this class is Acme.Collections.Stack. Třída obsahuje několik členů: pole s topnázvem, dvě metody pojmenované Push a Popa vnořená třída s názvem Entry.The class contains several members: a field named top, two methods named Push and Pop, and a nested class named Entry. Třída dále obsahuje tři členy: pole s názvem next, pole s názvem dataa konstruktor. EntryThe Entry class further contains three members: a field named next, a field named data, and a constructor. Za předpokladu, že zdrojový kód příkladu je uložen v souboru acme.cs, příkazový řádekAssuming that the source code of the example is stored in the file acme.cs, the command line

csc /t:library acme.cs

zkompiluje příklad jako knihovnu (kód bez Main vstupního bodu) a vytvoří sestavení s názvem. acme.dllcompiles the example as a library (code without a Main entry point) and produces an assembly named acme.dll.

Sestavení obsahují spustitelný kód ve formě instrukcí pro převodní jazyk (IL) a symbolické informace ve formě metadat.Assemblies contain executable code in the form of Intermediate Language (IL) instructions, and symbolic information in the form of metadata. Před provedením je kód IL v sestavení automaticky převeden na kód specifický pro procesor pomocí kompilátoru JIT (just-in-time) modulu CLR (Common Language Runtime) .NET.Before it is executed, the IL code in an assembly is automatically converted to processor-specific code by the Just-In-Time (JIT) compiler of .NET Common Language Runtime.

Vzhledem k tomu, že sestavení je samo-popisující jednotku funkcí obsahující kód i metadata, není nutné #include direktivy a hlavičkové soubory v. C#Because an assembly is a self-describing unit of functionality containing both code and metadata, there is no need for #include directives and header files in C#. Veřejné typy a členy, které jsou obsaženy v konkrétním sestavení, jsou v C# programu k dispozici jednoduše odkazem na toto sestavení při kompilování programu.The public types and members contained in a particular assembly are made available in a C# program simply by referencing that assembly when compiling the program. Například tento program používá Acme.Collections.Stack třídu acme.dll ze sestavení:For example, this program uses the Acme.Collections.Stack class from the acme.dll assembly:

using System;
using Acme.Collections;

class Test
{
    static void Main() {
        Stack s = new Stack();
        s.Push(1);
        s.Push(10);
        s.Push(100);
        Console.WriteLine(s.Pop());
        Console.WriteLine(s.Pop());
        Console.WriteLine(s.Pop());
    }
}

Pokud je program test.csuložen v souboru, když test.cs je zkompilován, acme.dll /r sestavení lze odkazovat pomocí možnosti kompilátoru:If the program is stored in the file test.cs, when test.cs is compiled, the acme.dll assembly can be referenced using the compiler's /r option:

csc /r:acme.dll test.cs

Tím se vytvoří spustitelné sestavení s test.exenázvem, které při spuštění vytvoří výstup:This creates an executable assembly named test.exe, which, when run, produces the output:

100
10
1

C#umožňuje, aby byl zdrojový text programu uložen v několika zdrojových souborech.C# permits the source text of a program to be stored in several source files. Když je zkompilován program pro C# více souborů, všechny zdrojové soubory jsou zpracovávány společně a zdrojové soubory mohou volně odkazovat, a to koncepční, protože všechny zdrojové soubory byly před zpracováním sloučeny do jednoho velkého souboru.When a multi-file C# program is compiled, all of the source files are processed together, and the source files can freely reference each other—conceptually, it is as if all the source files were concatenated into one large file before being processed. Dopředné deklarace nejsou nikdy C# potřeba v důsledku nedostatečných výjimek, pořadí deklarací je nedůležité.Forward declarations are never needed in C# because, with very few exceptions, declaration order is insignificant. C#neomezuje zdrojový soubor na deklaraci pouze jednoho veřejného typu, ani nevyžaduje název zdrojového souboru, aby odpovídal typu deklarovanému ve zdrojovém souboru.C# does not limit a source file to declaring only one public type nor does it require the name of the source file to match a type declared in the source file.

Typy a proměnnéTypes and variables

Existují dva druhy typů v C#: typy hodnot a typy odkazů.There are two kinds of types in C#: value types and reference types. Proměnné typů hodnot přímo obsahují svá data, zatímco proměnné typu odkazu ukládají odkazy na jejich data, přičemž ta se označují jako objekty.Variables of value types directly contain their data whereas variables of reference types store references to their data, the latter being known as objects. U typů odkazů je možné, aby dvě proměnné odkazovaly na stejný objekt a bylo tak možné, aby operace s jednou proměnnou ovlivnily objekt, na který je odkazováno z jiné proměnné.With reference types, it is possible for two variables to reference the same object and thus possible for operations on one variable to affect the object referenced by the other variable. S typy hodnot mají proměnné, které mají svou vlastní kopii dat, a není možné, aby operace na jednom byly ovlivněny druhou (kromě případu ref a out proměnných parametrů).With value types, the variables each have their own copy of the data, and it is not possible for operations on one to affect the other (except in the case of ref and out parameter variables).

C#typy hodnot jsou dále rozděleny na jednoduché typy, výčtové typy, typy strukturya typy s možnou hodnotou nulla C#odkazové typy jsou dále rozděleny do typů tříd, typů rozhraní, pole typya typy delegátů.C#'s value types are further divided into simple types, enum types, struct types, and nullable types, and C#'s reference types are further divided into class types, interface types, array types, and delegate types.

Následující tabulka poskytuje přehled C#systému typů.The following table provides an overview of C#'s type system.

KategorieCategory PopisDescription
Typy hodnotValue types Jednoduché typySimple types Podepsané integrály sbyte: short, int,,longSigned integral: sbyte, short, int, long
Unsigned integrál: byte, ushort, uint,ulongUnsigned integral: byte, ushort, uint, ulong
Znaky Unicode:charUnicode characters: char
Plovoucí desetinná čárka IEEE: float,doubleIEEE floating point: float, double
Desetinné číslo s vysokou přesností:decimalHigh-precision decimal: decimal
DatovéhoboolBoolean: bool
Výčtové typyEnum types Uživatelem definované typy formulářeenum E {...}User-defined types of the form enum E {...}
Typy strukturyStruct types Uživatelem definované typy formulářestruct S {...}User-defined types of the form struct S {...}
Typy s povolenou hodnotou NullNullable types Rozšíření všech ostatních typů hodnot s null hodnotouExtensions of all other value types with a null value
Typy odkazůReference types Typy třídClass types Nejvyšší základní třída všech ostatních typů:objectUltimate base class of all other types: object
Řetězce Unicode:stringUnicode strings: string
Uživatelem definované typy formulářeclass C {...}User-defined types of the form class C {...}
Typy rozhraníInterface types Uživatelem definované typy formulářeinterface I {...}User-defined types of the form interface I {...}
Typy políArray types Jednoduché a multidimenzionální, například int[] aint[,]Single- and multi-dimensional, for example, int[] and int[,]
Typy delegátůDelegate types Uživatelem definované typy formuláře, např.delegate int D(...)User-defined types of the form e.g. delegate int D(...)

Osm integrálních typů poskytuje podporu pro 8bitové, 16bitové, 32 a 64 hodnoty v podepsané nebo nepodepsané formě.The eight integral types provide support for 8-bit, 16-bit, 32-bit, and 64-bit values in signed or unsigned form.

Dva typy float s plovoucí desetinnou čárkou a doublejsou reprezentovány pomocí 32 formátů IEEE 754 s jednoduchou přesností a 64.The two floating point types, float and double, are represented using the 32-bit single-precision and 64-bit double-precision IEEE 754 formats.

decimal Typ je 128 datový typ, který je vhodný pro finanční a peněžní výpočty.The decimal type is a 128-bit data type suitable for financial and monetary calculations.

C#typ se používá k reprezentaci logických hodnot – hodnot, které true jsou buď nebo false. boolC#'s bool type is used to represent boolean values—values that are either true or false.

Zpracování znaků a řetězců v C# nástroji používá kódování Unicode.Character and string processing in C# uses Unicode encoding. Typ představuje jednotku kódu UTF-16 string a typ představuje sekvenci jednotek kódu UTF-16. charThe char type represents a UTF-16 code unit, and the string type represents a sequence of UTF-16 code units.

Následující tabulka shrnuje C#číselné typy.The following table summarizes C#'s numeric types.

KategorieCategory BitBits TypType Rozsah/přesnostRange/Precision
Podepsaný integrálSigned integral 88 sbyte -128...127-128...127
1616 short -32 768... 32, 767-32,768...32,767
3232 int -2147483648... 2, 147, 483, 647-2,147,483,648...2,147,483,647
6464 long -9223372036854775808... 9, 223, 372, 036, 854, 0,75, 807-9,223,372,036,854,775,808...9,223,372,036,854,775,807
Integrál bez znaménkaUnsigned integral 88 byte 0... 2550...255
1616 ushort 0... 65, 5350...65,535
3232 uint 0... 4, 294, 967, 2950...4,294,967,295
6464 ulong 0... 18, 446, 744, 073, 709, 551, 6150...18,446,744,073,709,551,615
Číslo s plovoucí desetinnou čárkouFloating point 3232 float 1,5 × 10 ^ − 45 až 3,4 × 10 ^ 38, 7 – přesnost číslic1.5 × 10^−45 to 3.4 × 10^38, 7-digit precision
6464 double 5,0 × 10 ^ − 324 a 1,7 × 10 ^ 308, přesnost na 15 číslic5.0 × 10^−324 to 1.7 × 10^308, 15-digit precision
DecimalDecimal 128128 decimal 1,0 × 10 ^ − 28 až 7,9 × 10 ^ 28, 28 číslic – přesnost1.0 × 10^−28 to 7.9 × 10^28, 28-digit precision

C#programy používají deklarace typů k vytváření nových typů.C# programs use type declarations to create new types. Deklarace typu Určuje název a členy nového typu.A type declaration specifies the name and the members of the new type. C#Pět kategorií typů je uživatelsky definované: typy tříd, typy struktury, typy rozhraní, výčtové typy a typy delegátů.Five of C#'s categories of types are user-definable: class types, struct types, interface types, enum types, and delegate types.

Typ třídy definuje datovou strukturu obsahující datové členy (pole) a členy funkce (metody, vlastnosti a další).A class type defines a data structure that contains data members (fields) and function members (methods, properties, and others). Typy tříd podporují jednu dědičnost a polymorfismus, mechanismy, které mohou odvozené třídy roztáhnout a specializovat základní třídy.Class types support single inheritance and polymorphism, mechanisms whereby derived classes can extend and specialize base classes.

Typ struktury je podobný typu třídy v tom, že představuje strukturu s datovými členy a členy funkce.A struct type is similar to a class type in that it represents a structure with data members and function members. Nicméně na rozdíl od tříd, struktury jsou typy hodnot a nevyžadují přidělení haldy.However, unlike classes, structs are value types and do not require heap allocation. Typy struktury nepodporují uživatelem zadanou dědičnost a všechny typy struktury implicitně dědí z typu object.Struct types do not support user-specified inheritance, and all struct types implicitly inherit from type object.

Typ rozhraní definuje kontrakt jako pojmenovanou sadu členů veřejné funkce.An interface type defines a contract as a named set of public function members. Třída nebo struktura, která implementuje rozhraní, musí poskytovat implementace členů funkce rozhraní.A class or struct that implements an interface must provide implementations of the interface's function members. Rozhraní může dědit z více základních rozhraní a třída nebo struktura může implementovat více rozhraní.An interface may inherit from multiple base interfaces, and a class or struct may implement multiple interfaces.

Typ delegáta představuje odkazy na metody s konkrétním seznamem parametrů a návratovým typem.A delegate type represents references to methods with a particular parameter list and return type. Delegáti umožňují zacházet s metodami jako s entitami, které lze přiřadit proměnným a předávat jako parametry.Delegates make it possible to treat methods as entities that can be assigned to variables and passed as parameters. Delegáti jsou podobní pojmu ukazatelů na funkce nalezené v některých jiných jazycích, ale na rozdíl od ukazatelů na funkce jsou delegáti objektově orientované a typově bezpečné.Delegates are similar to the concept of function pointers found in some other languages, but unlike function pointers, delegates are object-oriented and type-safe.

Třídy, struktura, rozhraní a typy delegátů podporují obecné typy, kde je lze parametrizovanit s jinými typy.Class, struct, interface and delegate types all support generics, whereby they can be parameterized with other types.

Typ výčtu je odlišný typ s pojmenovanými konstantami.An enum type is a distinct type with named constants. Každý typ výčtu má podkladový typ, který musí být jedním z osmi integrálních typů.Every enum type has an underlying type, which must be one of the eight integral types. Sada hodnot typu výčtu je stejná jako sada hodnot základního typu.The set of values of an enum type is the same as the set of values of the underlying type.

C#podporuje jedno a multidimenzionální pole libovolného typu.C# supports single- and multi-dimensional arrays of any type. Na rozdíl od typů uvedených výše nemusí být typy polí deklarovány dříve, než mohou být použity.Unlike the types listed above, array types do not have to be declared before they can be used. Místo toho jsou typy polí konstruovány pomocí názvu typu s hranatými závorkami.Instead, array types are constructed by following a type name with square brackets. int[] Například je int int int[][] jednorozměrné pole int[,] , je dvourozměrné pole, a je jednorozměrné pole jednorozměrného pole v rámci. intFor example, int[] is a single-dimensional array of int, int[,] is a two-dimensional array of int, and int[][] is a single-dimensional array of single-dimensional arrays of int.

Typy s možnou hodnotou null také nemusí být deklarovány dříve, než mohou být použity.Nullable types also do not have to be declared before they can be used. Pro každý typ T hodnoty, která není null, existuje odpovídající typ T?s možnou hodnotou null, který může nullobsahovat další hodnotu.For each non-nullable value type T there is a corresponding nullable type T?, which can hold an additional value null. Například je typ, který může obsahovat libovolné celé číslo 32 nebo hodnotu null. int?For instance, int? is a type that can hold any 32 bit integer or the value null.

C#systém typů je sjednocený tak, že hodnota libovolného typu může být zpracována jako objekt.C#'s type system is unified such that a value of any type can be treated as an object. Každý typ C# přímo nebo nepřímo je odvozen z object typu třídy a object je nejvyšší základní třídou všech typů.Every type in C# directly or indirectly derives from the object class type, and object is the ultimate base class of all types. Hodnoty typů odkazů se považují za objekty pouhým zobrazením hodnot jako typu object.Values of reference types are treated as objects simply by viewing the values as type object. Hodnoty typů hodnot se považují za objekty prováděním operací zabalení a rozbalení .Values of value types are treated as objects by performing boxing and unboxing operations. V následujícím příkladu int je hodnota převedena na object a zpět na int.In the following example, an int value is converted to object and back again to int.

using System;

class Test
{
    static void Main() {
        int i = 123;
        object o = i;          // Boxing
        int j = (int)o;        // Unboxing
    }
}

Je-li hodnota typu hodnoty převedena na typ object, je přidělena instance objektu, která se také označuje jako "pole", pro uchování hodnoty a hodnota je zkopírována do tohoto pole.When a value of a value type is converted to type object, an object instance, also called a "box," is allocated to hold the value, and the value is copied into that box. Naopak, pokud object je odkaz přetypování na typ hodnoty, je provedena kontrolu, že odkazovaný objekt je pole správného typu hodnoty, a pokud je ověření úspěšné, je hodnota v poli zkopírována.Conversely, when an object reference is cast to a value type, a check is made that the referenced object is a box of the correct value type, and, if the check succeeds, the value in the box is copied out.

C#Sjednocený typ systému efektivně znamená, že typy hodnot se můžou stát objekty na vyžádání.C#'s unified type system effectively means that value types can become objects "on demand." Z důvodu sjednocení, knihovny pro obecné účely, které používají typ object , lze použít s oběma typy odkazů i s typy hodnot.Because of the unification, general-purpose libraries that use type object can be used with both reference types and value types.

Existuje několik druhů proměnných v C#, včetně polí, prvků pole, místních proměnných a parametrů.There are several kinds of variables in C#, including fields, array elements, local variables, and parameters. Proměnné reprezentují umístění úložiště a každá proměnná má typ, který určuje, jaké hodnoty mohou být uloženy v proměnné, jak je znázorněno v následující tabulce.Variables represent storage locations, and every variable has a type that determines what values can be stored in the variable, as shown by the following table.

Typ proměnnéType of Variable Možný obsahPossible Contents
Typ hodnoty, která není nullNon-nullable value type Hodnota, která má přesný typA value of that exact type
Typ hodnoty s možnou hodnotou nullNullable value type Hodnota null nebo hodnota daného přesného typuA null value or a value of that exact type
object Odkaz s hodnotou null, odkaz na objekt libovolného typu odkazu nebo odkaz na zabalenou hodnotu libovolného typu hodnotyA null reference, a reference to an object of any reference type, or a reference to a boxed value of any value type
Typ třídyClass type Odkaz s hodnotou null, odkaz na instanci tohoto typu třídy nebo odkaz na instanci třídy odvozené z tohoto typu třídyA null reference, a reference to an instance of that class type, or a reference to an instance of a class derived from that class type
Typ rozhraníInterface type Odkaz s hodnotou null, odkaz na instanci typu třídy, který implementuje tento typ rozhraní, nebo odkaz na zabalenou hodnotu typu hodnoty, který implementuje tento typ rozhraníA null reference, a reference to an instance of a class type that implements that interface type, or a reference to a boxed value of a value type that implements that interface type
Typ poleArray type Odkaz s hodnotou null, odkaz na instanci tohoto typu pole nebo odkaz na instanci kompatibilního typu poleA null reference, a reference to an instance of that array type, or a reference to an instance of a compatible array type
Typ delegátaDelegate type Odkaz s hodnotou null nebo odkaz na instanci tohoto typu delegátaA null reference or a reference to an instance of that delegate type

VýrazyExpressions

Výrazy jsou vytvořené z operandů a operátorů.Expressions are constructed from operands and operators. Operátory výrazu označují, které operace se mají použít u operandů.The operators of an expression indicate which operations to apply to the operands. Příklady operátorů zahrnují +, -, * /, a .newExamples of operators include +, -, *, /, and new. Příklady operandů zahrnují literály, pole, místní proměnné a výrazy.Examples of operands include literals, fields, local variables, and expressions.

Pokud výraz obsahuje více operátorů, Priorita operátorů řídí pořadí, ve kterém jsou jednotlivé operátory vyhodnocovány.When an expression contains multiple operators, the precedence of the operators controls the order in which the individual operators are evaluated. Například výraz x + y * z je vyhodnocen jako x + (y * z) , protože * operátor má vyšší prioritu než + operátor.For example, the expression x + y * z is evaluated as x + (y * z) because the * operator has higher precedence than the + operator.

Většina operátorů může být přetížená.Most operators can be overloaded. Přetížení operátoru umožňuje zadat uživatelsky definované implementace operátorů pro operace, u nichž jeden nebo oba operandy jsou uživatelsky definovaný typ třídy nebo struktury.Operator overloading permits user-defined operator implementations to be specified for operations where one or both of the operands are of a user-defined class or struct type.

Následující tabulka shrnuje C#operátory, které obsahují kategorie operátora v pořadí podle priority od nejvyšších po nejnižší.The following table summarizes C#'s operators, listing the operator categories in order of precedence from highest to lowest. Operátory ve stejné kategorii mají stejnou prioritu.Operators in the same category have equal precedence.

KategorieCategory VyjádřeníExpression PopisDescription
PrimárníPrimary x.m Přístup ke členůmMember access
x(...) Vyvolání metod a delegátůMethod and delegate invocation
x[...] Přístup k poli a indexeruArray and indexer access
x++ PostinkrementacePost-increment
x-- PostdekrementacePost-decrement
new T(...) Vytvoření objektu a delegátuObject and delegate creation
new T(...){...} Vytvoření objektu s inicializátoremObject creation with initializer
new {...} Inicializátor anonymních objektůAnonymous object initializer
new T[...] Vytvoření poleArray creation
typeof(T) Získat System.Type objekt proTObtain System.Type object for T
checked(x) Vyhodnocení výrazu ve zkontrolovaném kontextuEvaluate expression in checked context
unchecked(x) Vyhodnocení výrazu v nezkontrolovaném kontextuEvaluate expression in unchecked context
default(T) Získat výchozí hodnotu typuTObtain default value of type T
delegate {...} Anonymní funkce (anonymní metoda)Anonymous function (anonymous method)
UnárníUnary +x IdentitaIdentity
-x NegaceNegation
!x Logická negaceLogical negation
~x Bitová negace.Bitwise negation
++x PreinkrementacePre-increment
--x PredekrementacePre-decrement
(T)x Explicitně převést x na typTExplicitly convert x to type T
await x Asynchronní čekání x na dokončeníAsynchronously wait for x to complete
MultiplikativníMultiplicative x * y NásobeníMultiplication
x / y DěleníDivision
x % y ZbytekRemainder
PřičítánímAdditive x + y Sčítání, řetězení řetězců, kombinování delegátůAddition, string concatenation, delegate combination
x - y Odčítání, odebrání delegátůSubtraction, delegate removal
SHIFTShift x << y Posun dolevaShift left
x >> y Posun dopravaShift right
Relační testování a testování typuRelational and type testing x < y Je menší nežLess than
x > y Je větší nežGreater than
x <= y Menší nebo rovnoLess than or equal
x >= y Větší nebo rovnoGreater than or equal
x is T Vrátí true ,TPokud x je, jinakfalseReturn true if x is a T, false otherwise
x as T Typ x se vrátí Tjako nebo null Pokud x neníTReturn x typed as T, or null if x is not a T
RovnostEquality x == y RovnoEqual
x != y Nerovná seNot equal
Logický operátor ANDLogical AND x & y Celočíselná bitová a logická logická hodnotaInteger bitwise AND, boolean logical AND
Logický operátor XORLogical XOR x ^ y Bitový operátor XOR celého čísla, logická hodnota operátoru XORInteger bitwise XOR, boolean logical XOR
Logický operátor ORLogical OR x | y Bitový operátor OR celého čísla, logická hodnota operátoru ORInteger bitwise OR, boolean logical OR
Podmiňovací operátor ANDConditional AND x && y Vyhodnotí xpouzev případě, že je y``trueEvaluates y only if x is true
Podmiňovací operátor ORConditional OR x || y Vyhodnotí xpouzev případě, že je y``falseEvaluates y only if x is false
Nulové sloučeníNull coalescing x ?? y Vyhodnotí jako x v null x případě, že je, do jiného yEvaluates to y if x is null, to x otherwise
Podmiňovací operátorConditional x ? y : z x true z Vyhodnotíx , pokud je, pokud je y``falseEvaluates y if x is true, z if x is false
Přiřazení nebo anonymní funkceAssignment or anonymous function x = y PřiřazeníAssignment
x op= y Složené přiřazení; podporované operátory jsou *= /= %= += -= <<= >>= &= ^=|=Compound assignment; supported operators are *= /= %= += -= <<= >>= &= ^= |=
(T x) => y Anonymní funkce (výraz lambda)Anonymous function (lambda expression)

PříkazyStatements

Akce programu jsou vyjádřeny pomocí příkazů.The actions of a program are expressed using statements. C#podporuje několik různých druhů příkazů, jejichž počet je definován z podmínek vložených příkazů.C# supports several different kinds of statements, a number of which are defined in terms of embedded statements.

Blok povoluje zápis více příkazů v kontextech, kde je povolen jediný příkaz.A block permits multiple statements to be written in contexts where a single statement is allowed. Blok obsahuje seznam příkazů zapsaných mezi oddělovači { a. }A block consists of a list of statements written between the delimiters { and }.

Příkazy deklarace slouží k deklaraci lokálních proměnných a konstant.Declaration statements are used to declare local variables and constants.

Příkazy výrazů se používají k vyhodnocení výrazů.Expression statements are used to evaluate expressions. Výrazy, které lze použít jako příkazy, zahrnují vyvolání metod, přidělení objektů pomocí new operátoru, přiřazení pomocí = operátorů a složené operátory přiřazení, zvýšení a snížení provozu pomocí ++operátory and a await. --Expressions that can be used as statements include method invocations, object allocations using the new operator, assignments using = and the compound assignment operators, increment and decrement operations using the ++ and -- operators and await expressions.

Příkazy výběru se používají k výběru jednoho z několika možných příkazů pro spuštění na základě hodnoty nějakého výrazu.Selection statements are used to select one of a number of possible statements for execution based on the value of some expression. V této skupině jsou if příkazy a. switchIn this group are the if and switch statements.

Příkazy iterace se používají k opakovanému provedení vloženého příkazu.Iteration statements are used to repeatedly execute an embedded statement. V této whileskupině jsou foreach příkazy, do, fora.In this group are the while, do, for, and foreach statements.

Příkazy skoku slouží k přenosu ovládacího prvku.Jump statements are used to transfer control. V této skupině jsou breakpříkazy, continue, goto, throw, returna. yieldIn this group are the break, continue, goto, throw, return, and yield statements.

try... příkaz slouží k zachycení výjimek, ke kterým dojde během provádění bloku, trya... catch finally příkaz slouží k určení výsledného kódu, který je vždy spuštěn, zda došlo k výjimce nebo nikoli.The try...catch statement is used to catch exceptions that occur during execution of a block, and the try...finally statement is used to specify finalization code that is always executed, whether an exception occurred or not.

Příkazy checked aunchecked slouží k řízení kontextu kontroly přetečení pro aritmetické operace a převody integrálního typu.The checked and unchecked statements are used to control the overflow checking context for integral-type arithmetic operations and conversions.

lock Příkaz slouží k získání zámku vzájemného vyloučení pro daný objekt, spuštění příkazu a uvolnění zámku.The lock statement is used to obtain the mutual-exclusion lock for a given object, execute a statement, and then release the lock.

using Příkaz slouží k získání prostředku, spuštění příkazu a následnému uvolnění tohoto prostředku.The using statement is used to obtain a resource, execute a statement, and then dispose of that resource.

Níže jsou uvedeny příklady každého typu příkazu.Below are examples of each kind of statement

Deklarace místních proměnnýchLocal variable declarations

static void Main() {
   int a;
   int b = 2, c = 3;
   a = 1;
   Console.WriteLine(a + b + c);
}

Deklarace místní konstantyLocal constant declaration

static void Main() {
    const float pi = 3.1415927f;
    const int r = 25;
    Console.WriteLine(pi * r * r);
}

Příkaz výrazuExpression statement

static void Main() {
    int i;
    i = 123;                // Expression statement
    Console.WriteLine(i);   // Expression statement
    i++;                    // Expression statement
    Console.WriteLine(i);   // Expression statement
}

ifvydáif statement

static void Main(string[] args) {
    if (args.Length == 0) {
        Console.WriteLine("No arguments");
    }
    else {
        Console.WriteLine("One or more arguments");
    }
}

switchvydáswitch statement

static void Main(string[] args) {
    int n = args.Length;
    switch (n) {
        case 0:
            Console.WriteLine("No arguments");
            break;
        case 1:
            Console.WriteLine("One argument");
            break;
        default:
            Console.WriteLine("{0} arguments", n);
            break;
    }
}

whilevydáwhile statement

static void Main(string[] args) {
    int i = 0;
    while (i < args.Length) {
        Console.WriteLine(args[i]);
        i++;
    }
}

dovydádo statement

static void Main() {
    string s;
    do {
        s = Console.ReadLine();
        if (s != null) Console.WriteLine(s);
    } while (s != null);
}

forvydáfor statement

static void Main(string[] args) {
    for (int i = 0; i < args.Length; i++) {
        Console.WriteLine(args[i]);
    }
}

foreachvydáforeach statement

static void Main(string[] args) {
    foreach (string s in args) {
        Console.WriteLine(s);
    }
}

breakvydábreak statement

static void Main() {
    while (true) {
        string s = Console.ReadLine();
        if (s == null) break;
        Console.WriteLine(s);
    }
}

continuevydácontinue statement

static void Main(string[] args) {
    for (int i = 0; i < args.Length; i++) {
        if (args[i].StartsWith("/")) continue;
        Console.WriteLine(args[i]);
    }
}

gotovydágoto statement

static void Main(string[] args) {
    int i = 0;
    goto check;
    loop:
    Console.WriteLine(args[i++]);
    check:
    if (i < args.Length) goto loop;
}

returnvydáreturn statement

static int Add(int a, int b) {
    return a + b;
}

static void Main() {
    Console.WriteLine(Add(1, 2));
    return;
}

yieldvydáyield statement

static IEnumerable<int> Range(int from, int to) {
    for (int i = from; i < to; i++) {
        yield return i;
    }
    yield break;
}

static void Main() {
    foreach (int x in Range(-10,10)) {
        Console.WriteLine(x);
    }
}

throwpříkazy try athrow and try statements

static double Divide(double x, double y) {
    if (y == 0) throw new DivideByZeroException();
    return x / y;
}

static void Main(string[] args) {
    try {
        if (args.Length != 2) {
            throw new Exception("Two numbers required");
        }
        double x = double.Parse(args[0]);
        double y = double.Parse(args[1]);
        Console.WriteLine(Divide(x, y));
    }
    catch (Exception e) {
        Console.WriteLine(e.Message);
    }
    finally {
        Console.WriteLine("Good bye!");
    }
}

checkedpříkazy unchecked achecked and unchecked statements

static void Main() {
    int i = int.MaxValue;
    checked {
        Console.WriteLine(i + 1);        // Exception
    }
    unchecked {
        Console.WriteLine(i + 1);        // Overflow
    }
}

lockvydálock statement

class Account
{
    decimal balance;
    public void Withdraw(decimal amount) {
        lock (this) {
            if (amount > balance) {
                throw new Exception("Insufficient funds");
            }
            balance -= amount;
        }
    }
}

usingvydáusing statement

static void Main() {
    using (TextWriter w = File.CreateText("test.txt")) {
        w.WriteLine("Line one");
        w.WriteLine("Line two");
        w.WriteLine("Line three");
    }
}

Třídy a objektyClasses and objects

Třídy jsou základem C#typů.Classes are the most fundamental of C#'s types. Třída je datová struktura, která kombinuje stav (pole) a akce (metody a další členy funkce) v jedné jednotce.A class is a data structure that combines state (fields) and actions (methods and other function members) in a single unit. Třída poskytuje definici pro dynamicky vytvořené instance třídy, označované také jako objekty.A class provides a definition for dynamically created instances of the class, also known as objects. Třídy podporují Dědičnost a polymorfismus, mechanismy, kterými mohou odvozené třídy roztáhnout a specializovat základní třídy.Classes support inheritance and polymorphism, mechanisms whereby derived classes can extend and specialize base classes.

Nové třídy jsou vytvářeny pomocí deklarací třídy.New classes are created using class declarations. Deklarace třídy začíná hlavičkou, která určuje atributy a modifikátory třídy, název třídy, základní třídu (Pokud je daná) a rozhraní implementovaná třídou.A class declaration starts with a header that specifies the attributes and modifiers of the class, the name of the class, the base class (if given), and the interfaces implemented by the class. Pod hlavičkou následuje tělo třídy, které se skládá ze seznamu deklarací členů napsaných mezi oddělovači { a. }The header is followed by the class body, which consists of a list of member declarations written between the delimiters { and }.

Následuje deklarace jednoduché třídy s názvem Point:The following is a declaration of a simple class named Point:

public class Point
{
    public int x, y;

    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }
}

Instance tříd jsou vytvořeny pomocí new operátoru, který přiděluje paměť pro novou instanci, vyvolá konstruktor pro inicializaci instance a vrátí odkaz na instanci.Instances of classes are created using the new operator, which allocates memory for a new instance, invokes a constructor to initialize the instance, and returns a reference to the instance. Následující příkazy vytvoří dva Point objekty a ukládají odkazy na tyto objekty ve dvou proměnných:The following statements create two Point objects and store references to those objects in two variables:

Point p1 = new Point(0, 0);
Point p2 = new Point(10, 20);

Paměť obsazená objektem je automaticky uvolněna, pokud se objekt již nepoužívá.The memory occupied by an object is automatically reclaimed when the object is no longer in use. Není ani možné explicitně zrušit přidělení objektů v C#.It is neither necessary nor possible to explicitly deallocate objects in C#.

MembersMembers

Členy třídy jsou buď statické členy , nebo členy instance.The members of a class are either static members or instance members. Statické členy patří ke třídám a členy instance patří do objektů (instance tříd).Static members belong to classes, and instance members belong to objects (instances of classes).

Následující tabulka poskytuje přehled druhů členů, které třída může obsahovat.The following table provides an overview of the kinds of members a class can contain.

ČlenMember PopisDescription
KonstantyConstants Konstantní hodnoty přidružené ke tříděConstant values associated with the class
Fields (Pole)Fields Proměnné třídyVariables of the class
MetodyMethods Výpočty a akce, které mohou být provedeny třídouComputations and actions that can be performed by the class
propertiesProperties Akce spojené s čtením a zápisem s názvem vlastnosti třídyActions associated with reading and writing named properties of the class
IndexeryIndexers Akce přidružené k indexování instancí třídy, jako je poleActions associated with indexing instances of the class like an array
DurationEvents Oznámení, která mohou být vygenerována třídouNotifications that can be generated by the class
OperátoryOperators Převody a operátory výrazů podporované třídouConversions and expression operators supported by the class
KonstruktoryConstructors Akce vyžadované pro inicializaci instancí třídy nebo samotné třídyActions required to initialize instances of the class or the class itself
DestruktoryDestructors Akce, které se mají provést před tím, než se instance třídy trvale zahodíActions to perform before instances of the class are permanently discarded
TypyTypes Vnořené typy deklarované třídouNested types declared by the class

PřístupnostAccessibility

Každý člen třídy má přidruženou přístupnost, která řídí oblasti textu programu, které mají přístup k členu.Each member of a class has an associated accessibility, which controls the regions of program text that are able to access the member. Existuje pět možných forem usnadnění přístupu.There are five possible forms of accessibility. Tyto jsou shrnuté v následující tabulce.These are summarized in the following table.

UsnadněníAccessibility SmysluMeaning
public Přístup není omezenýAccess not limited
protected Přístup omezený na tuto třídu nebo třídy odvozené z této třídyAccess limited to this class or classes derived from this class
internal Přístup omezený na tento programAccess limited to this program
protected internal Přístup omezený na tento program nebo třídy odvozené z této třídyAccess limited to this program or classes derived from this class
private Přístup omezený na tuto tříduAccess limited to this class

Parametry typuType parameters

Definice třídy může určovat sadu parametrů typu za názvem třídy a lomenými závorkami ohraničující seznam názvů parametrů typu.A class definition may specify a set of type parameters by following the class name with angle brackets enclosing a list of type parameter names. Parametry typu lze použít v těle deklarací třídy k definování členů třídy.The type parameters can the be used in the body of the class declarations to define the members of the class. V následujícím příkladu parametry Pair typu jsou TFirst a TSecond:In the following example, the type parameters of Pair are TFirst and TSecond:

public class Pair<TFirst,TSecond>
{
    public TFirst First;
    public TSecond Second;
}

Typ třídy, která je deklarována pro přijetí parametrů typu, se nazývá typ obecné třídy.A class type that is declared to take type parameters is called a generic class type. Typy struktury, rozhraní a delegátů můžou být také obecné.Struct, interface and delegate types can also be generic.

Při použití obecné třídy je nutné zadat argumenty typu pro každý z parametrů typu:When the generic class is used, type arguments must be provided for each of the type parameters:

Pair<int,string> pair = new Pair<int,string> { First = 1, Second = "two" };
int i = pair.First;     // TFirst is int
string s = pair.Second; // TSecond is string

Obecný typ s poskytnutými argumenty typu, jako Pair<int,string> je například výše, se označuje jako konstruovaný typ.A generic type with type arguments provided, like Pair<int,string> above, is called a constructed type.

Základní třídyBase classes

Deklarace třídy může specifikovat základní třídu za názvem třídy a parametry typu s dvojtečkou a názvem základní třídy.A class declaration may specify a base class by following the class name and type parameters with a colon and the name of the base class. Vynechání specifikace základní třídy je stejné jako odvození z typu object.Omitting a base class specification is the same as deriving from type object. V následujícím příkladu Point3D je základní třída třídy Point Point a základní třída object:In the following example, the base class of Point3D is Point, and the base class of Point is object:

public class Point
{
    public int x, y;

    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }
}

public class Point3D: Point
{
    public int z;

    public Point3D(int x, int y, int z): base(x, y) {
        this.z = z;
    }
}

Třída dědí členy své základní třídy.A class inherits the members of its base class. Dědičnost znamená, že třída implicitně obsahuje všechny členy své základní třídy, s výjimkou instancí a statických konstruktorů a destruktorů základní třídy.Inheritance means that a class implicitly contains all members of its base class, except for the instance and static constructors, and the destructors of the base class. Odvozená třída může přidat nové členy do těch, které dědí, ale nemůže odebrat definici zděděného člena.A derived class can add new members to those it inherits, but it cannot remove the definition of an inherited member. V předchozím příkladu Point3D x dědí pole a y z Pointa každá Point3D instance obsahuje tři pole, x, ya z.In the previous example, Point3D inherits the x and y fields from Point, and every Point3D instance contains three fields, x, y, and z.

Implicitní převod existuje z typu třídy na libovolný z jeho základních typů třídy.An implicit conversion exists from a class type to any of its base class types. Proto proměnná typu třídy může odkazovat na instanci této třídy nebo instanci jakékoli odvozené třídy.Therefore, a variable of a class type can reference an instance of that class or an instance of any derived class. Například s ohledem na předchozí deklarace třídy může proměnná typu Point odkazovat buď na Point , nebo Point3D:For example, given the previous class declarations, a variable of type Point can reference either a Point or a Point3D:

Point a = new Point(10, 20);
Point b = new Point3D(10, 20, 30);

Fields (Pole)Fields

Pole je proměnná, která je přidružena ke třídě nebo s instancí třídy.A field is a variable that is associated with a class or with an instance of a class.

Pole deklarované s static modifikátorem definuje statické pole.A field declared with the static modifier defines a static field. Statické pole identifikuje právě jedno umístění úložiště.A static field identifies exactly one storage location. Bez ohledu na to, kolik instancí třídy je vytvořeno, existuje pouze jedna kopie statického pole.No matter how many instances of a class are created, there is only ever one copy of a static field.

Pole deklarované bez static modifikátoru definuje pole instance.A field declared without the static modifier defines an instance field. Každá instance třídy obsahuje samostatnou kopii všech polí instance této třídy.Every instance of a class contains a separate copy of all the instance fields of that class.

V následujícím příkladu má Color každá instance třídy samostatnou kopii rpolí Blackinstance, ga b Red, ale je k dispozici pouze jedna kopie, White,, Green aBlue statická pole:In the following example, each instance of the Color class has a separate copy of the r, g, and b instance fields, but there is only one copy of the Black, White, Red, Green, and Blue static fields:

public class Color
{
    public static readonly Color Black = new Color(0, 0, 0);
    public static readonly Color White = new Color(255, 255, 255);
    public static readonly Color Red = new Color(255, 0, 0);
    public static readonly Color Green = new Color(0, 255, 0);
    public static readonly Color Blue = new Color(0, 0, 255);
    private byte r, g, b;

    public Color(byte r, byte g, byte b) {
        this.r = r;
        this.g = g;
        this.b = b;
    }
}

Jak je znázorněno v předchozím příkladu, pole jen pro čtení mohou být deklarována readonly s modifikátorem.As shown in the previous example, read-only fields may be declared with a readonly modifier. Přiřazení k readonly poli může být provedeno pouze v rámci deklarace pole nebo v konstruktoru ve stejné třídě.Assignment to a readonly field can only occur as part of the field's declaration or in a constructor in the same class.

MetodyMethods

Metoda je člen, který implementuje výpočet nebo akci, kterou lze provést pomocí objektu nebo třídy.A method is a member that implements a computation or action that can be performed by an object or class. Statické metody jsou k dispozici prostřednictvím třídy.Static methods are accessed through the class. Metody instance jsou k dispozici prostřednictvím instancí třídy.Instance methods are accessed through instances of the class.

Metody mají (pravděpodobně prázdný) seznam parametrů, které reprezentují hodnoty nebo odkazy na proměnné předané metodě a návratový typ, který určuje typ počítané hodnoty a vrácený metodou.Methods have a (possibly empty) list of parameters, which represent values or variable references passed to the method, and a return type, which specifies the type of the value computed and returned by the method. Návratový typ metody je void , pokud nevrací hodnotu.A method's return type is void if it does not return a value.

Podobně jako typy mohou metody mít také sadu parametrů typu, pro které argumenty typu musí být zadány při volání metody.Like types, methods may also have a set of type parameters, for which type arguments must be specified when the method is called. Na rozdíl od typů lze argumenty typu často odvodit z argumentů volání metody a nemusí být explicitně předány.Unlike types, the type arguments can often be inferred from the arguments of a method call and need not be explicitly given.

Signatura metody musí být jedinečná ve třídě, ve které je metoda deklarovaná.The signature of a method must be unique in the class in which the method is declared. Signatura metody se skládá z názvu metody, počtu parametrů typu a počtu, modifikátorů a typů jeho parametrů.The signature of a method consists of the name of the method, the number of type parameters and the number, modifiers, and types of its parameters. Podpis metody nezahrnuje návratový typ.The signature of a method does not include the return type.

ParametryParameters

Parametry slouží k předání hodnot nebo odkazů na proměnné metody.Parameters are used to pass values or variable references to methods. Parametry metody získají jejich skutečné hodnoty z argumentů , které jsou zadány při volání metody.The parameters of a method get their actual values from the arguments that are specified when the method is invoked. Existují čtyři typy parametrů: parametry hodnoty, parametry odkazu, výstupní parametry a pole parametrů.There are four kinds of parameters: value parameters, reference parameters, output parameters, and parameter arrays.

Parametr hodnoty se používá pro předávání vstupních parametrů.A value parameter is used for input parameter passing. Parametr hodnoty odpovídá místní proměnné, která vrací počáteční hodnotu z argumentu předaného pro parametr.A value parameter corresponds to a local variable that gets its initial value from the argument that was passed for the parameter. Úpravy parametru hodnoty neovlivňují argument, který byl předán parametru.Modifications to a value parameter do not affect the argument that was passed for the parameter.

Parametry hodnoty mohou být volitelné, zadáním výchozí hodnoty, aby bylo možné vynechat odpovídající argumenty.Value parameters can be optional, by specifying a default value so that corresponding arguments can be omitted.

Parametr reference se používá pro předávání vstupních i výstupních parametrů.A reference parameter is used for both input and output parameter passing. Argument předaný parametru reference musí být proměnná a během provádění metody představuje parametr reference stejné umístění úložiště jako proměnná argumentu.The argument passed for a reference parameter must be a variable, and during execution of the method, the reference parameter represents the same storage location as the argument variable. Parametr reference je deklarován s ref modifikátorem.A reference parameter is declared with the ref modifier. Následující příklad ukazuje použití ref parametrů.The following example shows the use of ref parameters.

using System;

class Test
{
    static void Swap(ref int x, ref int y) {
        int temp = x;
        x = y;
        y = temp;
    }

    static void Main() {
        int i = 1, j = 2;
        Swap(ref i, ref j);
        Console.WriteLine("{0} {1}", i, j);            // Outputs "2 1"
    }
}

Výstupní parametr se používá pro předávání výstupního parametru.An output parameter is used for output parameter passing. Výstupní parametr je podobný referenčnímu parametru s tím rozdílem, že počáteční hodnota argumentu zadaného volajícího je neimportovaná.An output parameter is similar to a reference parameter except that the initial value of the caller-provided argument is unimportant. Výstupní parametr je deklarován s out modifikátorem.An output parameter is declared with the out modifier. Následující příklad ukazuje použití out parametrů.The following example shows the use of out parameters.

using System;

class Test
{
    static void Divide(int x, int y, out int result, out int remainder) {
        result = x / y;
        remainder = x % y;
    }

    static void Main() {
        int res, rem;
        Divide(10, 3, out res, out rem);
        Console.WriteLine("{0} {1}", res, rem);    // Outputs "3 1"
    }
}

Pole parametrů povoluje proměnný počet argumentů, které mají být předány metodě.A parameter array permits a variable number of arguments to be passed to a method. Pole parametrů je deklarováno s params modifikátorem.A parameter array is declared with the params modifier. Pouze poslední parametr metody může být pole parametrů a typ pole parametrů musí být jednorozměrné pole.Only the last parameter of a method can be a parameter array, and the type of a parameter array must be a single-dimensional array type. Metody Write aWriteLine třídy jsou osvědčenými příklady použití pole parametrů. System.ConsoleThe Write and WriteLine methods of the System.Console class are good examples of parameter array usage. Jsou deklarovány následujícím způsobem.They are declared as follows.

public class Console
{
    public static void Write(string fmt, params object[] args) {...}
    public static void WriteLine(string fmt, params object[] args) {...}
    ...
}

V rámci metody, která používá pole parametrů, se pole parametru chová stejně jako regulární parametr typu pole.Within a method that uses a parameter array, the parameter array behaves exactly like a regular parameter of an array type. Při vyvolání metody s parametrem pole je však možné předat buď jeden argument typu pole parametru, nebo libovolný počet argumentů typu prvku pole parametrů.However, in an invocation of a method with a parameter array, it is possible to pass either a single argument of the parameter array type or any number of arguments of the element type of the parameter array. V druhém případě je instance pole automaticky vytvořena a inicializována s danými argumenty.In the latter case, an array instance is automatically created and initialized with the given arguments. Tento příkladThis example

Console.WriteLine("x={0} y={1} z={2}", x, y, z);

je ekvivalentem zápisu následujícího.is equivalent to writing the following.

string s = "x={0} y={1} z={2}";
object[] args = new object[3];
args[0] = x;
args[1] = y;
args[2] = z;
Console.WriteLine(s, args);

Tělo metody a místní proměnnéMethod body and local variables

Tělo metody Určuje příkazy, které mají být provedeny při volání metody.A method's body specifies the statements to execute when the method is invoked.

Tělo metody může deklarovat proměnné, které jsou specifické pro vyvolání metody.A method body can declare variables that are specific to the invocation of the method. Tyto proměnné se nazývají místní proměnné.Such variables are called local variables. Místní deklarace proměnné Určuje název typu, název proměnné a pravděpodobně počáteční hodnotu.A local variable declaration specifies a type name, a variable name, and possibly an initial value. Následující příklad deklaruje místní proměnnou i s počáteční hodnotou nula a místní proměnnou j bez počáteční hodnoty.The following example declares a local variable i with an initial value of zero and a local variable j with no initial value.

using System;

class Squares
{
    static void Main() {
        int i = 0;
        int j;
        while (i < 10) {
            j = i * i;
            Console.WriteLine("{0} x {0} = {1}", i, j);
            i = i + 1;
        }
    }
}

C#aby bylo možné získat hodnotu, musí být místní proměnná jednoznačně přiřazena .C# requires a local variable to be definitely assigned before its value can be obtained. Například pokud deklarace předchozí i nezahrnuje počáteční hodnotu, kompilátor by nahlásil chybu pro následné použití i , protože i by se v těchto bodech v programu nedala jednoznačně přiřadit.For example, if the declaration of the previous i did not include an initial value, the compiler would report an error for the subsequent usages of i because i would not be definitely assigned at those points in the program.

Metoda může použít return příkazy pro vrácení řízení volajícímu.A method can use return statements to return control to its caller. V metodách, voidkteré return vracejí, příkazy nemohou určovat výraz.In a method returning void, return statements cannot specify an expression. V metodě, která vrací nonvoid- return , příkazy musí obsahovat výraz, který vypočítá vrácenou hodnotu.In a method returning non-void, return statements must include an expression that computes the return value.

Statické a instanční metodyStatic and instance methods

Metoda deklarovaná s static modifikátorem je statická metoda.A method declared with a static modifier is a static method. Statická metoda nepracuje na konkrétní instanci a může přímo přistupovat ke statickým členům.A static method does not operate on a specific instance and can only directly access static members.

Metoda deklarovaná bez static modifikátoru je Metoda instance.A method declared without a static modifier is an instance method. Metoda instance pracuje na konkrétní instanci a může přistupovat ke statickým i instancím členů.An instance method operates on a specific instance and can access both static and instance members. Instance, na které byla vyvolána metoda instance, může být explicitně k dispozici jako this.The instance on which an instance method was invoked can be explicitly accessed as this. V případě, že se odkazuje na this statickou metodu, se jedná o chybu.It is an error to refer to this in a static method.

Následující Entity třída má členy statických i instancí.The following Entity class has both static and instance members.

class Entity
{
    static int nextSerialNo;
    int serialNo;

    public Entity() {
        serialNo = nextSerialNo++;
    }

    public int GetSerialNo() {
        return serialNo;
    }

    public static int GetNextSerialNo() {
        return nextSerialNo;
    }

    public static void SetNextSerialNo(int value) {
        nextSerialNo = value;
    }
}

Každá Entity instance obsahuje sériové číslo (a předpokládá se, že některé další informace nejsou zde uvedeny).Each Entity instance contains a serial number (and presumably some other information that is not shown here). Entity Konstruktor (který je jako metoda instance) Inicializuje novou instanci s dalším dostupným sériovým číslem.The Entity constructor (which is like an instance method) initializes the new instance with the next available serial number. Vzhledem k tomu, že je konstruktor členem instance, je povolen přístup serialNo k poli instance i k nextSerialNo statickému poli.Because the constructor is an instance member, it is permitted to access both the serialNo instance field and the nextSerialNo static field.

Statické metody SetNextSerialNoamůžou přistupovat ke serialNo statickému poli, ale při přímém přístupu k poli instance by to byla chyba. nextSerialNo GetNextSerialNoThe GetNextSerialNo and SetNextSerialNo static methods can access the nextSerialNo static field, but it would be an error for them to directly access the serialNo instance field.

Následující příklad ukazuje použití Entity třídy.The following example shows the use of the Entity class.

using System;

class Test
{
    static void Main() {
        Entity.SetNextSerialNo(1000);
        Entity e1 = new Entity();
        Entity e2 = new Entity();
        Console.WriteLine(e1.GetSerialNo());           // Outputs "1000"
        Console.WriteLine(e2.GetSerialNo());           // Outputs "1001"
        Console.WriteLine(Entity.GetNextSerialNo());   // Outputs "1002"
    }
}

Všimněte si, SetNextSerialNo že GetNextSerialNo statické metody a jsou vyvolány GetSerialNo ve třídě, zatímco metoda instance je vyvolána na instancích třídy.Note that the SetNextSerialNo and GetNextSerialNo static methods are invoked on the class whereas the GetSerialNo instance method is invoked on instances of the class.

Virtuální, přepisování a abstraktní metodyVirtual, override, and abstract methods

Pokud deklarace metody instance obsahuje virtual modifikátor, metoda je označována jako virtuální metoda.When an instance method declaration includes a virtual modifier, the method is said to be a virtual method. Pokud není virtual k dispozici žádný modifikátor, metoda je označována jako nevirtuální metoda.When no virtual modifier is present, the method is said to be a non-virtual method.

Když je vyvolána virtuální metoda, je typ běhu instance, pro kterou probíhá vyvolání, určuje vlastní implementaci metody, která má být vyvolána.When a virtual method is invoked, the run-time type of the instance for which that invocation takes place determines the actual method implementation to invoke. V nevirtuálním volání metody je Typ doby kompilace instance určujícím faktorem.In a nonvirtual method invocation, the compile-time type of the instance is the determining factor.

Virtuální metoda může být přepsána v odvozené třídě.A virtual method can be overridden in a derived class. Když deklarace metody instance obsahuje override modifikátor, metoda přepíše zděděnou virtuální metodu se stejnou signaturou.When an instance method declaration includes an override modifier, the method overrides an inherited virtual method with the same signature. Zatímco deklarace virtuální metody zavádí novou metodu, deklarace metody přepsání specializuje existující zděděnou virtuální metodu tím, že poskytuje novou implementaci této metody.Whereas a virtual method declaration introduces a new method, an override method declaration specializes an existing inherited virtual method by providing a new implementation of that method.

Abstraktní metoda je virtuální metoda bez implementace.An abstract method is a virtual method with no implementation. Abstraktní metoda je deklarována s abstract modifikátorem a je povolena pouze ve třídě, která je deklarována abstracttaké.An abstract method is declared with the abstract modifier and is permitted only in a class that is also declared abstract. Abstraktní metoda musí být přepsána v každé neabstraktní odvozené třídě.An abstract method must be overridden in every non-abstract derived class.

Následující příklad deklaruje abstraktní Expressiontřídu,, která představuje uzel stromu výrazu, a tři odvozené třídy, Constant, VariableReference, a Operation, které implementují uzly stromu výrazů pro konstanty, proměnnou odkazy a aritmetické operace.The following example declares an abstract class, Expression, which represents an expression tree node, and three derived classes, Constant, VariableReference, and Operation, which implement expression tree nodes for constants, variable references, and arithmetic operations. (To je podobné, ale nelze je zaměňovat s typy stromu výrazů představenými ve stromových typech výrazů).(This is similar to, but not to be confused with the expression tree types introduced in Expression tree types).

using System;
using System.Collections;

public abstract class Expression
{
    public abstract double Evaluate(Hashtable vars);
}

public class Constant: Expression
{
    double value;

    public Constant(double value) {
        this.value = value;
    }

    public override double Evaluate(Hashtable vars) {
        return value;
    }
}

public class VariableReference: Expression
{
    string name;

    public VariableReference(string name) {
        this.name = name;
    }

    public override double Evaluate(Hashtable vars) {
        object value = vars[name];
        if (value == null) {
            throw new Exception("Unknown variable: " + name);
        }
        return Convert.ToDouble(value);
    }
}

public class Operation: Expression
{
    Expression left;
    char op;
    Expression right;

    public Operation(Expression left, char op, Expression right) {
        this.left = left;
        this.op = op;
        this.right = right;
    }

    public override double Evaluate(Hashtable vars) {
        double x = left.Evaluate(vars);
        double y = right.Evaluate(vars);
        switch (op) {
            case '+': return x + y;
            case '-': return x - y;
            case '*': return x * y;
            case '/': return x / y;
        }
        throw new Exception("Unknown operator");
    }
}

K modelování aritmetických výrazů lze použít předchozí čtyři třídy.The previous four classes can be used to model arithmetic expressions. Například pomocí instancí těchto tříd může být výraz x + 3 reprezentován následujícím způsobem.For example, using instances of these classes, the expression x + 3 can be represented as follows.

Expression e = new Operation(
    new VariableReference("x"),
    '+',
    new Constant(3));

Metoda instance je vyvolána pro vyhodnocení double daného výrazu a vytvoření hodnoty. Expression EvaluateThe Evaluate method of an Expression instance is invoked to evaluate the given expression and produce a double value. Metoda přebírá jako argument a Hashtable , který obsahuje názvy proměnných (jako klíče záznamů) a hodnoty (jako hodnoty položek).The method takes as an argument a Hashtable that contains variable names (as keys of the entries) and values (as values of the entries). Evaluate Metoda je virtuální abstraktní metoda, což znamená, že neabstraktní odvozené třídy musí přepsat, aby poskytovala skutečnou implementaci.The Evaluate method is a virtual abstract method, meaning that non-abstract derived classes must override it to provide an actual implementation.

Constant ImplementacejednoduševrátíEvaluate uloženou konstantu.A Constant's implementation of Evaluate simply returns the stored constant. Implementace VariableReferenceobjektu vyhledá název proměnné v zatřiďovací tabulce a vrátí výslednou hodnotu.A VariableReference's implementation looks up the variable name in the hashtable and returns the resulting value. Implementace nejprve vyhodnotí levý a pravý operand (rekurzivním Evaluate voláním metod) a poté provede danou aritmetickou operaci. OperationAn Operation's implementation first evaluates the left and right operands (by recursively invoking their Evaluate methods) and then performs the given arithmetic operation.

Následující program používá Expression třídy pro vyhodnocení výrazu x * (y + 2) pro různé hodnoty x a y.The following program uses the Expression classes to evaluate the expression x * (y + 2) for different values of x and y.

using System;
using System.Collections;

class Test
{
    static void Main() {
        Expression e = new Operation(
            new VariableReference("x"),
            '*',
            new Operation(
                new VariableReference("y"),
                '+',
                new Constant(2)
            )
        );
        Hashtable vars = new Hashtable();
        vars["x"] = 3;
        vars["y"] = 5;
        Console.WriteLine(e.Evaluate(vars));        // Outputs "21"
        vars["x"] = 1.5;
        vars["y"] = 9;
        Console.WriteLine(e.Evaluate(vars));        // Outputs "16.5"
    }
}

Přetížení metodyMethod overloading

Přetížení metody umožňuje, aby více metod ve stejné třídě měl stejný název, pokud mají jedinečné podpisy.Method overloading permits multiple methods in the same class to have the same name as long as they have unique signatures. Při kompilování volání přetížené metody kompilátor používá řešení přetížení k určení konkrétní metody, která má být vyvolána.When compiling an invocation of an overloaded method, the compiler uses overload resolution to determine the specific method to invoke. Řešení přetížení najde jednu metodu, která nejlépe odpovídá argumentům, nebo hlásí chybu, pokud nelze najít žádnou nejlepší shodu.Overload resolution finds the one method that best matches the arguments or reports an error if no single best match can be found. Následující příklad ukazuje rozlišení přetížení v platnosti.The following example shows overload resolution in effect. Komentář pro každé vyvolání v Main metodě ukazuje, která metoda je skutečně vyvolána.The comment for each invocation in the Main method shows which method is actually invoked.

class Test
{
    static void F() {
        Console.WriteLine("F()");
    }

    static void F(object x) {
        Console.WriteLine("F(object)");
    }

    static void F(int x) {
        Console.WriteLine("F(int)");
    }

    static void F(double x) {
        Console.WriteLine("F(double)");
    }

    static void F<T>(T x) {
        Console.WriteLine("F<T>(T)");
    }

    static void F(double x, double y) {
        Console.WriteLine("F(double, double)");
    }

    static void Main() {
        F();                 // Invokes F()
        F(1);                // Invokes F(int)
        F(1.0);              // Invokes F(double)
        F("abc");            // Invokes F(object)
        F((double)1);        // Invokes F(double)
        F((object)1);        // Invokes F(object)
        F<int>(1);           // Invokes F<T>(T)
        F(1, 1);             // Invokes F(double, double)
    }
}

Jak je znázorněno v příkladu, konkrétní metodu lze vždy vybrat explicitním přetypováním argumentů na přesné typy parametrů a/nebo explicitním zadáním argumentů typu.As shown by the example, a particular method can always be selected by explicitly casting the arguments to the exact parameter types and/or explicitly supplying type arguments.

Další členové funkcíOther function members

Členy, které obsahují spustitelný kód, jsou souhrnně označovány jako Členové funkce třídy.Members that contain executable code are collectively known as the function members of a class. Předchozí část popisuje metody, které jsou hlavním typem členů funkce.The preceding section describes methods, which are the primary kind of function members. Tato část popisuje další druhy členů funkce, které C#podporuje: konstruktory, vlastnosti, indexery, události, operátory a destruktory.This section describes the other kinds of function members supported by C#: constructors, properties, indexers, events, operators, and destructors.

Následující kód ukazuje obecnou třídu s názvem List<T>, která implementuje zvětšený seznam objektů.The following code shows a generic class called List<T>, which implements a growable list of objects. Třída obsahuje několik příkladů nejběžnějších druhů členů funkce.The class contains several examples of the most common kinds of function members.

public class List<T> {
    // Constant...
    const int defaultCapacity = 4;

    // Fields...
    T[] items;
    int count;

    // Constructors...
    public List(int capacity = defaultCapacity) {
        items = new T[capacity];
    }

    // Properties...
    public int Count {
        get { return count; }
    }
    public int Capacity {
        get {
            return items.Length;
        }
        set {
            if (value < count) value = count;
            if (value != items.Length) {
                T[] newItems = new T[value];
                Array.Copy(items, 0, newItems, 0, count);
                items = newItems;
            }
        }
    }

    // Indexer...
    public T this[int index] {
        get {
            return items[index];
        }
        set {
            items[index] = value;
            OnChanged();
        }
    }

    // Methods...
    public void Add(T item) {
        if (count == Capacity) Capacity = count * 2;
        items[count] = item;
        count++;
        OnChanged();
    }
    protected virtual void OnChanged() {
        if (Changed != null) Changed(this, EventArgs.Empty);
    }
    public override bool Equals(object other) {
        return Equals(this, other as List<T>);
    }
    static bool Equals(List<T> a, List<T> b) {
        if (a == null) return b == null;
        if (b == null || a.count != b.count) return false;
        for (int i = 0; i < a.count; i++) {
            if (!object.Equals(a.items[i], b.items[i])) {
                return false;
            }
        }
        return true;
    }

    // Event...
    public event EventHandler Changed;

    // Operators...
    public static bool operator ==(List<T> a, List<T> b) {
        return Equals(a, b);
    }
    public static bool operator !=(List<T> a, List<T> b) {
        return !Equals(a, b);
    }
}

KonstruktoryConstructors

C#podporuje jak instance, tak statické konstruktory.C# supports both instance and static constructors. Konstruktor instance je člen, který implementuje akce vyžadované pro inicializaci instance třídy.An instance constructor is a member that implements the actions required to initialize an instance of a class. Statický konstruktor je člen, který implementuje akce vyžadované k inicializaci samotné třídy při prvním načtení.A static constructor is a member that implements the actions required to initialize a class itself when it is first loaded.

Konstruktor je deklarovaný jako metoda bez návratového typu a stejný název jako obsahující třída.A constructor is declared like a method with no return type and the same name as the containing class. Pokud deklarace konstruktoru obsahuje static modifikátor, deklaruje statický konstruktor.If a constructor declaration includes a static modifier, it declares a static constructor. V opačném případě deklaruje konstruktor instance.Otherwise, it declares an instance constructor.

Konstruktory instancí mohou být přetíženy.Instance constructors can be overloaded. Například List<T> třída deklaruje dva konstruktory instancí, jednu bez parametrů a jednu, která int přijímá parametr.For example, the List<T> class declares two instance constructors, one with no parameters and one that takes an int parameter. Konstruktory instancí jsou vyvolány new pomocí operátoru.Instance constructors are invoked using the new operator. Následující příkazy přidělují dvě List<string> instance pomocí každého konstruktoru List třídy.The following statements allocate two List<string> instances using each of the constructors of the List class.

List<string> list1 = new List<string>();
List<string> list2 = new List<string>(10);

Na rozdíl od jiných členů nejsou konstruktory instancí zděděny a třída nemá žádné konstruktory instancí jiné než ty, které jsou ve třídě skutečně deklarovány.Unlike other members, instance constructors are not inherited, and a class has no instance constructors other than those actually declared in the class. Pokud pro třídu není zadán konstruktor instance, bude automaticky zadáno prázdné číslo bez parametrů.If no instance constructor is supplied for a class, then an empty one with no parameters is automatically provided.

propertiesProperties

Vlastnosti jsou přirozené rozšíření polí.Properties are a natural extension of fields. Oba se nazývají členové s přidruženými typy a syntaxe pro přístup k polím a vlastnostem je stejná.Both are named members with associated types, and the syntax for accessing fields and properties is the same. Na rozdíl od polí ale vlastnosti neoznačují umístění úložiště.However, unlike fields, properties do not denote storage locations. Místo toho mají vlastnosti přistupující objekty , které určují příkazy, které mají být provedeny, když jsou jejich hodnoty čteny nebo zapsány.Instead, properties have accessors that specify the statements to be executed when their values are read or written.

Vlastnost je deklarována jako pole s tím rozdílem, že deklarace končí pomocí get přístupového objektu nebo set přístupového objektu napsaného { mezi oddělovači } a místo ukončení středníkem.A property is declared like a field, except that the declaration ends with a get accessor and/or a set accessor written between the delimiters { and } instead of ending in a semicolon. get Vlastnost, která má přistupující objekt set i přistupující objekt get , je vlastnost pro čtení i zápis, vlastnost, která má pouze přistupující objekt, je vlastnost jen pro čtenía vlastnost, která má pouze set přistupující objekt, je. vlastnost pouze pro zápis.A property that has both a get accessor and a set accessor is a read-write property, a property that has only a get accessor is a read-only property, and a property that has only a set accessor is a write-only property.

get Přistupující objekt odpovídá metodě bez parametrů s návratovou hodnotou typu vlastnosti.A get accessor corresponds to a parameterless method with a return value of the property type. S výjimkou cíle přiřazení, při odkazování na vlastnost ve výrazu, get je vyvolána přístup k vlastnosti pro výpočet hodnoty vlastnosti.Except as the target of an assignment, when a property is referenced in an expression, the get accessor of the property is invoked to compute the value of the property.

Přistupující objekt odpovídá metodě s jediným parametrem s názvem value a bez návratového typu. setA set accessor corresponds to a method with a single parameter named value and no return type. Když je na vlastnost odkazováno jako na cíl přiřazení nebo jako operand ++ nebo --, set je objekt přistupující vyvolán s argumentem, který poskytuje novou hodnotu.When a property is referenced as the target of an assignment or as the operand of ++ or --, the set accessor is invoked with an argument that provides the new value.

Třída deklaruje dvě vlastnosti Count Capacity, které jsou jen pro čtení a pro čtení i zápis, v uvedeném pořadí. List<T>The List<T> class declares two properties, Count and Capacity, which are read-only and read-write, respectively. Následuje příklad použití těchto vlastností.The following is an example of use of these properties.

List<string> names = new List<string>();
names.Capacity = 100;            // Invokes set accessor
int i = names.Count;             // Invokes get accessor
int j = names.Capacity;          // Invokes get accessor

Podobně jako pole a metody C# podporuje vlastnosti instance i statické vlastnosti.Similar to fields and methods, C# supports both instance properties and static properties. Statické vlastnosti jsou deklarovány s static modifikátorem a vlastnosti instance jsou deklarovány bez ní.Static properties are declared with the static modifier, and instance properties are declared without it.

Přístupové objekty vlastnosti mohou být virtuální.The accessor(s) of a property can be virtual. Pokud deklarace vlastnosti obsahuje virtualmodifikátor, abstractnebo override , vztahuje se na přístupový objekt (y) vlastnosti.When a property declaration includes a virtual, abstract, or override modifier, it applies to the accessor(s) of the property.

IndexeryIndexers

Indexer je člen, který umožňuje, aby objekty byly indexovány stejným způsobem jako pole.An indexer is a member that enables objects to be indexed in the same way as an array. Indexer je deklarován jako vlastnost s tím rozdílem, že název člena je this následován seznamem parametrů napsaným mezi [ oddělovači a ].An indexer is declared like a property except that the name of the member is this followed by a parameter list written between the delimiters [ and ]. Parametry jsou k dispozici v přistupujícím objektu indexeru.The parameters are available in the accessor(s) of the indexer. Podobně jako u vlastností mohou být indexery pro čtení i zápis, jen pro čtení a přístup k nástroji indexeru, které mohou být virtuální.Similar to properties, indexers can be read-write, read-only, and write-only, and the accessor(s) of an indexer can be virtual.

Třída deklaruje jeden indexer pro čtení a zápis, který int přebírá parametr. ListThe List class declares a single read-write indexer that takes an int parameter. Indexer umožňuje indexovat List instance s int hodnotami.The indexer makes it possible to index List instances with int values. NapříkladFor example

List<string> names = new List<string>();
names.Add("Liz");
names.Add("Martha");
names.Add("Beth");
for (int i = 0; i < names.Count; i++) {
    string s = names[i];
    names[i] = s.ToUpper();
}

Indexery mohou být přetíženy, což znamená, že třída může deklarovat více indexerů za předpokladu, že počet nebo typy jejich parametrů se liší.Indexers can be overloaded, meaning that a class can declare multiple indexers as long as the number or types of their parameters differ.

DurationEvents

Událost je člen, který umožňuje třídě nebo objektu poskytovat oznámení.An event is a member that enables a class or object to provide notifications. Událost je deklarována jako pole s tím rozdílem, že deklarace event zahrnuje klíčové slovo a typ musí být delegovaný typ.An event is declared like a field except that the declaration includes an event keyword and the type must be a delegate type.

V rámci třídy, která deklaruje člena události, se událost chová stejně jako pole typu delegáta (za předpokladu, že událost není abstraktní a nedeklaruje přistupující objekty).Within a class that declares an event member, the event behaves just like a field of a delegate type (provided the event is not abstract and does not declare accessors). Pole ukládá odkaz na delegáta, který představuje obslužné rutiny událostí, které byly přidány do události.The field stores a reference to a delegate that represents the event handlers that have been added to the event. Pokud nejsou k dispozici žádné obslužné rutiny událostí null, pole je.If no event handles are present, the field is null.

Třída deklaruje jeden člen události s názvem Changed, který indikuje, že do seznamu byla přidána nová položka. List<T>The List<T> class declares a single event member called Changed, which indicates that a new item has been added to the list. Událost je vyvolána OnChanged virtuální metodou, která nejprve kontroluje, zda je null událost (to znamená, že nejsou přítomny žádné obslužné rutiny). ChangedThe Changed event is raised by the OnChanged virtual method, which first checks whether the event is null (meaning that no handlers are present). Pojem vyvolání události je přesně shodný s voláním delegáta reprezentovaného událostí, takže neexistují žádné speciální jazykové konstrukce pro vyvolání událostí.The notion of raising an event is precisely equivalent to invoking the delegate represented by the event—thus, there are no special language constructs for raising events.

Klienti reagují na události prostřednictvím obslužných rutin událostí.Clients react to events through event handlers. Obslužné rutiny událostí jsou připojeny += pomocí operátoru a odebrány -= pomocí operátoru.Event handlers are attached using the += operator and removed using the -= operator. Následující příklad připojí obslužnou rutinu události k Changed události. List<string>The following example attaches an event handler to the Changed event of a List<string>.

using System;

class Test
{
    static int changeCount;

    static void ListChanged(object sender, EventArgs e) {
        changeCount++;
    }

    static void Main() {
        List<string> names = new List<string>();
        names.Changed += new EventHandler(ListChanged);
        names.Add("Liz");
        names.Add("Martha");
        names.Add("Beth");
        Console.WriteLine(changeCount);        // Outputs "3"
    }
}

Pro pokročilé scénáře, kde je požadováno řízení základního úložiště události, může deklarace události explicitně poskytnout add a remove přistupující objekty, které set jsou poněkud podobné přístupovému objektu vlastnosti.For advanced scenarios where control of the underlying storage of an event is desired, an event declaration can explicitly provide add and remove accessors, which are somewhat similar to the set accessor of a property.

OperátoryOperators

Operátor je člen, který definuje význam použití konkrétního operátoru výrazu na instance třídy.An operator is a member that defines the meaning of applying a particular expression operator to instances of a class. Lze definovat tři typy operátorů: unární operátory, binární operátory a operátory převodu.Three kinds of operators can be defined: unary operators, binary operators, and conversion operators. Všechny operátory musí být deklarovány public jako statica.All operators must be declared as public and static.

Třída deklaruje dva operátory operator== List , a, a poskytuje tak nový význam pro výrazy, které tyto operátory aplikují na instance. operator!= List<T>The List<T> class declares two operators, operator== and operator!=, and thus gives new meaning to expressions that apply those operators to List instances. Konkrétně operátory definují rovnost dvou List<T> instancí jako porovnávání každého z obsažených objektů pomocí jejich Equals metod.Specifically, the operators define equality of two List<T> instances as comparing each of the contained objects using their Equals methods. Následující příklad používá == operátor k porovnání dvou List<int> instancí.The following example uses the == operator to compare two List<int> instances.

using System;

class Test
{
    static void Main() {
        List<int> a = new List<int>();
        a.Add(1);
        a.Add(2);
        List<int> b = new List<int>();
        b.Add(1);
        b.Add(2);
        Console.WriteLine(a == b);        // Outputs "True"
        b.Add(3);
        Console.WriteLine(a == b);        // Outputs "False"
    }
}

První Console.WriteLine výstupy True , protože dva seznamy obsahují stejný počet objektů se stejnými hodnotami ve stejném pořadí.The first Console.WriteLine outputs True because the two lists contain the same number of objects with the same values in the same order. a List<int> Nebyl definován operator==, False první Console.WriteLine by měl výstup, protože ab odkazují na různé instance. List<T>Had List<T> not defined operator==, the first Console.WriteLine would have output False because a and b reference different List<int> instances.

DestruktoryDestructors

Destruktor je člen, který implementuje akce vyžadované k destrukcií instance třídy.A destructor is a member that implements the actions required to destruct an instance of a class. Destruktory nemohou mít parametry, nemohou mít modifikátory dostupnosti a nelze je volat explicitně.Destructors cannot have parameters, they cannot have accessibility modifiers, and they cannot be invoked explicitly. Destruktor instance je vyvolán automaticky během uvolňování paměti.The destructor for an instance is invoked automatically during garbage collection.

Uvolňování paměti je povolená rozsáhlá Zeměpisná šířka při rozhodování o shromažďování objektů a spouštění destruktorů.The garbage collector is allowed wide latitude in deciding when to collect objects and run destructors. Konkrétně načasování volání destruktoru není deterministické a v jakémkoli vlákně mohou být provedeny destruktory.Specifically, the timing of destructor invocations is not deterministic, and destructors may be executed on any thread. Z těchto a dalších důvodů by třídy měly implementovat destruktory pouze v případě, že žádná jiná řešení nejsou proveditelná.For these and other reasons, classes should implement destructors only when no other solutions are feasible.

using Příkaz poskytuje lepší přístup k zničení objektu.The using statement provides a better approach to object destruction.

StrukturyStructs

Podobně jako třídy struktury jsou datové struktury, které mohou obsahovat datové členy a členy funkce, ale na rozdíl od tříd, struktury jsou typy hodnot a nevyžadují přidělení haldy.Like classes, structs are data structures that can contain data members and function members, but unlike classes, structs are value types and do not require heap allocation. Proměnná typu struktury přímo ukládá data struktury, zatímco proměnná typu třídy ukládá odkaz na dynamicky přidělený objekt.A variable of a struct type directly stores the data of the struct, whereas a variable of a class type stores a reference to a dynamically allocated object. Typy struktury nepodporují uživatelem zadanou dědičnost a všechny typy struktury implicitně dědí z typu object.Struct types do not support user-specified inheritance, and all struct types implicitly inherit from type object.

Struktury jsou zvláště užitečné pro malé datové struktury, které mají sémantiku hodnot.Structs are particularly useful for small data structures that have value semantics. Komplexní čísla, body v systému souřadnic nebo páry klíč-hodnota ve slovníku jsou všechny dobrými příklady struktur.Complex numbers, points in a coordinate system, or key-value pairs in a dictionary are all good examples of structs. Použití struktur namísto tříd pro malé datové struktury může mít velký rozdíl v počtu přidělení paměti, které aplikace provádí.The use of structs rather than classes for small data structures can make a large difference in the number of memory allocations an application performs. Například následující program vytvoří a inicializuje pole 100 bodů.For example, the following program creates and initializes an array of 100 points. V Point případě 101, že jsou implementovány jako třídy, jsou vytvořeny instance samostatných objektů – jeden pro pole a jeden pro prvky 100.With Point implemented as a class, 101 separate objects are instantiated—one for the array and one each for the 100 elements.

class Point
{
    public int x, y;

    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }
}

class Test
{
    static void Main() {
        Point[] points = new Point[100];
        for (int i = 0; i < 100; i++) points[i] = new Point(i, i);
    }
}

Alternativou je vytvoření Point struktury.An alternative is to make Point a struct.

struct Point
{
    public int x, y;

    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }
}

Nyní je vytvořena instance pouze jednoho objektu – jeden pro pole – a Point instance jsou uloženy v poli do pole.Now, only one object is instantiated—the one for the array—and the Point instances are stored in-line in the array.

Konstruktory struktury jsou vyvolány new pomocí operátoru, ale to neznamená, že se paměť přiděluje.Struct constructors are invoked with the new operator, but that does not imply that memory is being allocated. Namísto dynamického přidělování objektu a vrácení odkazu na něj konstruktor struktury jednoduše vrátí hodnotu samotné struktury (obvykle v dočasném umístění v zásobníku) a tato hodnota se pak podle potřeby zkopíruje.Instead of dynamically allocating an object and returning a reference to it, a struct constructor simply returns the struct value itself (typically in a temporary location on the stack), and this value is then copied as necessary.

U tříd je možné, aby dvě proměnné odkazovaly na stejný objekt a bylo tak možné, aby operace na jedné proměnné ovlivnily objekt, na který je odkazováno jinou proměnnou.With classes, it is possible for two variables to reference the same object and thus possible for operations on one variable to affect the object referenced by the other variable. Pomocí struktur mají proměnné, které mají svou vlastní kopii dat, a není možné, aby operace na jednom z nich ovlivnily druhou.With structs, the variables each have their own copy of the data, and it is not possible for operations on one to affect the other. Například výstup vyprodukovaný následujícím fragmentem kódu závisí na tom, zda Point je třída nebo struktura.For example, the output produced by the following code fragment depends on whether Point is a class or a struct.

Point a = new Point(10, 10);
Point b = a;
a.x = 20;
Console.WriteLine(b.x);

Pokud Point je třída, výstup je 20 , protože a a b odkazuje na stejný objekt.If Point is a class, the output is 20 because a and b reference the same object. Pokud Point je struktura, výstup je 10 , protože přiřazení a pro b vytvoří kopii hodnoty a tato kopie není ovlivněna následným přiřazením k a.x.If Point is a struct, the output is 10 because the assignment of a to b creates a copy of the value, and this copy is unaffected by the subsequent assignment to a.x.

Předchozí příklad zvýrazní dvě omezení struktury.The previous example highlights two of the limitations of structs. Nejprve kopírování celé struktury je obvykle méně efektivní než kopírování odkazu na objekt, takže předávání parametrů hodnot a parametrů může být dražší s strukturami, než s typem odkazu.First, copying an entire struct is typically less efficient than copying an object reference, so assignment and value parameter passing can be more expensive with structs than with reference types. Sekunda s ref výjimkou out parametrů a není možné vytvořit odkazy na struktury, které pravidla jejich používání vymění v řadě situací.Second, except for ref and out parameters, it is not possible to create references to structs, which rules out their usage in a number of situations.

PoleArrays

Pole je datová struktura, která obsahuje počet proměnných, které jsou dostupné prostřednictvím počítaných indexů.An array is a data structure that contains a number of variables that are accessed through computed indices. Proměnné obsažené v poli, označované také jako prvky pole, jsou všechny stejného typu a tento typ se nazývá typ elementu pole.The variables contained in an array, also called the elements of the array, are all of the same type, and this type is called the element type of the array.

Typy polí jsou odkazové typy a deklarace proměnné pole jednoduše nastaví volné místo pro odkaz na instanci pole.Array types are reference types, and the declaration of an array variable simply sets aside space for a reference to an array instance. Skutečné instance pole jsou vytvářeny dynamicky za běhu pomocí new operátoru.Actual array instances are created dynamically at run-time using the new operator. Operace určuje délku nové instance pole, která je poté opravena po dobu života instance. newThe new operation specifies the length of the new array instance, which is then fixed for the lifetime of the instance. Indexy prvků rozsahu pole od 0 do. Length - 1The indices of the elements of an array range from 0 to Length - 1. Operátor automaticky inicializuje prvky pole na výchozí hodnotu, což je například nula pro všechny číselné typy a null pro všechny typy odkazů. newThe new operator automatically initializes the elements of an array to their default value, which, for example, is zero for all numeric types and null for all reference types.

Následující příklad vytvoří pole int prvků, inicializuje pole a vytiskne obsah pole.The following example creates an array of int elements, initializes the array, and prints out the contents of the array.

using System;

class Test
{
    static void Main() {
        int[] a = new int[10];
        for (int i = 0; i < a.Length; i++) {
            a[i] = i * i;
        }
        for (int i = 0; i < a.Length; i++) {
            Console.WriteLine("a[{0}] = {1}", i, a[i]);
        }
    }
}

Tento příklad vytvoří a pracuje na jednorozměrném poli.This example creates and operates on a single-dimensional array. C#podporuje rovněž multidimenzionální pole.C# also supports multi-dimensional arrays. Počet rozměrů typu pole, označovaný také jako rozměr typu pole, je jedna plus počet čárek napsaných mezi hranatými závorkami typu pole.The number of dimensions of an array type, also known as the rank of the array type, is one plus the number of commas written between the square brackets of the array type. Následující příklad přiděluje jednorozměrné, dvourozměrné a trojrozměrné pole.The following example allocates a one-dimensional, a two-dimensional, and a three-dimensional array.

int[] a1 = new int[10];
int[,] a2 = new int[10, 5];
int[,,] a3 = new int[10, 5, 2];

Pole obsahuje 10 prvků a2 , pole obsahuje 50 (10 × 5 a3 ) prvků a pole obsahuje 100 (10 × 5 × 2) prvků. a1The a1 array contains 10 elements, the a2 array contains 50 (10 × 5) elements, and the a3 array contains 100 (10 × 5 × 2) elements.

Typ elementu pole může být libovolný typ, včetně typu pole.The element type of an array can be any type, including an array type. Pole s prvky typu pole se někdy nazývá vícenásobné pole , protože délky polí elementů nemusí být stejné.An array with elements of an array type is sometimes called a jagged array because the lengths of the element arrays do not all have to be the same. Následující příklad přiděluje pole polí pro int:The following example allocates an array of arrays of int:

int[][] a = new int[3][];
a[0] = new int[10];
a[1] = new int[5];
a[2] = new int[20];

První řádek vytvoří pole se třemi prvky, každý typ int[] a každý s počáteční nullhodnotou.The first line creates an array with three elements, each of type int[] and each with an initial value of null. Následující řádky poté inicializují tři prvky s odkazy na jednotlivé instance pole s různou délkou.The subsequent lines then initialize the three elements with references to individual array instances of varying lengths.

Operátor umožňuje zadat počáteční hodnoty prvků pole pomocí inicializátoru pole, což je seznam výrazů zapsaných mezi oddělovači { a. } newThe new operator permits the initial values of the array elements to be specified using an array initializer, which is a list of expressions written between the delimiters { and }. Následující příklad přiděluje a inicializuje int[] se třemi prvky.The following example allocates and initializes an int[] with three elements.

int[] a = new int[] {1, 2, 3};

Všimněte si, že délka pole je odvozena od počtu výrazů mezi { a. }Note that the length of the array is inferred from the number of expressions between { and }. Deklarace lokální proměnné a pole lze dále zkrátit tak, aby se typ pole nemuselo přestavit.Local variable and field declarations can be shortened further such that the array type does not have to be restated.

int[] a = {1, 2, 3};

Oba předchozí příklady jsou ekvivalentní následujícímu:Both of the previous examples are equivalent to the following:

int[] t = new int[3];
t[0] = 1;
t[1] = 2;
t[2] = 3;
int[] a = t;

RozhraníInterfaces

Rozhraní definuje kontrakt, který může být implementován pomocí tříd a struktur.An interface defines a contract that can be implemented by classes and structs. Rozhraní může obsahovat metody, vlastnosti, události a indexery.An interface can contain methods, properties, events, and indexers. Rozhraní neposkytuje implementace členů, které definuje – určuje pouze členy, které musí být poskytnuty třídami nebo strukturami, které implementují rozhraní.An interface does not provide implementations of the members it defines—it merely specifies the members that must be supplied by classes or structs that implement the interface.

Rozhraní mohou využívat vícenásobnou dědičnost.Interfaces may employ multiple inheritance. V následujícím příkladu rozhraní IComboBox dědí ITextBox z a IListBox.In the following example, the interface IComboBox inherits from both ITextBox and IListBox.

interface IControl
{
    void Paint();
}

interface ITextBox: IControl
{
    void SetText(string text);
}

interface IListBox: IControl
{
    void SetItems(string[] items);
}

interface IComboBox: ITextBox, IListBox {}

Třídy a struktury mohou implementovat více rozhraní.Classes and structs can implement multiple interfaces. V následujícím příkladu třída EditBox implementuje IDataBoundi IControl .In the following example, the class EditBox implements both IControl and IDataBound.

interface IDataBound
{
    void Bind(Binder b);
}

public class EditBox: IControl, IDataBound
{
    public void Paint() {...}
    public void Bind(Binder b) {...}
}

Pokud třída nebo struktura implementuje konkrétní rozhraní, instance této třídy nebo struktury lze implicitně převést na tento typ rozhraní.When a class or struct implements a particular interface, instances of that class or struct can be implicitly converted to that interface type. NapříkladFor example

EditBox editBox = new EditBox();
IControl control = editBox;
IDataBound dataBound = editBox;

V případech, kdy instance není staticky známá pro implementaci konkrétního rozhraní, lze použít dynamické přetypování typu.In cases where an instance is not statically known to implement a particular interface, dynamic type casts can be used. Například následující příkazy používají přetypování dynamického typu k získání implementace objektu IControl a IDataBound rozhraní.For example, the following statements use dynamic type casts to obtain an object's IControl and IDataBound interface implementations. Vzhledem k tomu, že skutečný typ objektu EditBoxje, přetypování je úspěšné.Because the actual type of the object is EditBox, the casts succeed.

object obj = new EditBox();
IControl control = (IControl)obj;
IDataBound dataBound = (IDataBound)obj;

V EditBox předchozí public třídě Paint je metoda IControl IDataBound z rozhraní a Metodazrozhraníimplementovánapomocíčlenů.BindIn the previous EditBox class, the Paint method from the IControl interface and the Bind method from the IDataBound interface are implemented using public members. C#podporuje také explicitní implementace členů rozhraní, pomocí kterých se třída nebo struktura může vyhnout vytváření členů public.C# also supports explicit interface member implementations, using which the class or struct can avoid making the members public. Explicitní implementace člena rozhraní je zapsána pomocí plně kvalifikovaného názvu člena rozhraní.An explicit interface member implementation is written using the fully qualified interface member name. Například EditBox třída může IControl.Paint implementovat metody a IDataBound.Bind pomocí explicitní implementace členů rozhraní následujícím způsobem.For example, the EditBox class could implement the IControl.Paint and IDataBound.Bind methods using explicit interface member implementations as follows.

public class EditBox: IControl, IDataBound
{
    void IControl.Paint() {...}
    void IDataBound.Bind(Binder b) {...}
}

K explicitním členům rozhraní lze přistupovat pouze prostřednictvím typu rozhraní.Explicit interface members can only be accessed via the interface type. Například implementaci IControl.Paint poskytovanou předchozí EditBox třídou lze EditBox vyvolat pouze první IControl převod odkazu na typ rozhraní.For example, the implementation of IControl.Paint provided by the previous EditBox class can only be invoked by first converting the EditBox reference to the IControl interface type.

EditBox editBox = new EditBox();
editBox.Paint();                        // Error, no such method
IControl control = editBox;
control.Paint();                        // Ok

VýčtyEnums

Typ výčtu je jedinečný typ hodnoty se sadou pojmenovaných konstant.An enum type is a distinct value type with a set of named constants. Následující příklad deklaruje a používá Color typ výčtu pojmenovaný se třemi konstantními hodnotami, Red, Greena Blue.The following example declares and uses an enum type named Color with three constant values, Red, Green, and Blue.

using System;

enum Color
{
    Red,
    Green,
    Blue
}

class Test
{
    static void PrintColor(Color color) {
        switch (color) {
            case Color.Red:
                Console.WriteLine("Red");
                break;
            case Color.Green:
                Console.WriteLine("Green");
                break;
            case Color.Blue:
                Console.WriteLine("Blue");
                break;
            default:
                Console.WriteLine("Unknown color");
                break;
        }
    }

    static void Main() {
        Color c = Color.Red;
        PrintColor(c);
        PrintColor(Color.Blue);
    }
}

Každý typ výčtu má odpovídající celočíselný typ nazvaný základní typ výčtového typu.Each enum type has a corresponding integral type called the underlying type of the enum type. Typ výčtu, který explicitně nedeklaruje nadřízený typ, má podkladový typ int.An enum type that does not explicitly declare an underlying type has an underlying type of int. Formát úložiště typu výčtu a rozsah možných hodnot jsou určeny podle jeho základního typu.An enum type's storage format and range of possible values are determined by its underlying type. Sada hodnot, na jejichž základě může typ výčtu pobírat, není omezena členy výčtu.The set of values that an enum type can take on is not limited by its enum members. Konkrétně jakákoli hodnota základního typu výčtu může být převedena na typ výčtu a je odlišná platná hodnota tohoto typu výčtu.In particular, any value of the underlying type of an enum can be cast to the enum type and is a distinct valid value of that enum type.

Následující příklad deklaruje typ výčtu s názvem Alignment s podkladovým sbytetypem.The following example declares an enum type named Alignment with an underlying type of sbyte.

enum Alignment: sbyte
{
    Left = -1,
    Center = 0,
    Right = 1
}

Jak je znázorněno v předchozím příkladu, deklarace člena výčtu může zahrnovat konstantní výraz, který určuje hodnotu člena.As shown by the previous example, an enum member declaration can include a constant expression that specifies the value of the member. Hodnota konstanty pro každého člena výčtu musí být v rozsahu nadřazeného typu výčtu.The constant value for each enum member must be in the range of the underlying type of the enum. Když deklarace člena výčtu explicitně neurčí hodnotu, členovi se předává hodnota nula (Pokud se jedná o první člen v typu výčtu) nebo hodnota dříve předcházejícího člena výčtu plus jedna.When an enum member declaration does not explicitly specify a value, the member is given the value zero (if it is the first member in the enum type) or the value of the textually preceding enum member plus one.

Hodnoty výčtu lze převést na integrální hodnoty a naopak pomocí přetypování typů.Enum values can be converted to integral values and vice versa using type casts. NapříkladFor example

int i = (int)Color.Blue;        // int i = 2;
Color c = (Color)2;             // Color c = Color.Blue;

Výchozí hodnota libovolného typu výčtu je celočíselná hodnota nula převedená na typ výčtu.The default value of any enum type is the integral value zero converted to the enum type. V případech, kdy jsou proměnné automaticky inicializovány na výchozí hodnotu, je tato hodnota předána proměnným typům výčtu.In cases where variables are automatically initialized to a default value, this is the value given to variables of enum types. Aby byla výchozí hodnota typu výčtu snadno dostupná, literál 0 implicitně převede na libovolný typ výčtu.In order for the default value of an enum type to be easily available, the literal 0 implicitly converts to any enum type. Proto jsou povoleny následující.Thus, the following is permitted.

Color c = 0;

DelegátyDelegates

Typ delegáta představuje odkazy na metody s konkrétním seznamem parametrů a návratovým typem.A delegate type represents references to methods with a particular parameter list and return type. Delegáti umožňují zacházet s metodami jako s entitami, které lze přiřadit proměnným a předávat jako parametry.Delegates make it possible to treat methods as entities that can be assigned to variables and passed as parameters. Delegáti jsou podobní pojmu ukazatelů na funkce nalezené v některých jiných jazycích, ale na rozdíl od ukazatelů na funkce jsou delegáti objektově orientované a typově bezpečné.Delegates are similar to the concept of function pointers found in some other languages, but unlike function pointers, delegates are object-oriented and type-safe.

Následující příklad deklaruje a používá typ delegáta s názvem Function.The following example declares and uses a delegate type named Function.

using System;

delegate double Function(double x);

class Multiplier
{
    double factor;

    public Multiplier(double factor) {
        this.factor = factor;
    }

    public double Multiply(double x) {
        return x * factor;
    }
}

class Test
{
    static double Square(double x) {
        return x * x;
    }

    static double[] Apply(double[] a, Function f) {
        double[] result = new double[a.Length];
        for (int i = 0; i < a.Length; i++) result[i] = f(a[i]);
        return result;
    }

    static void Main() {
        double[] a = {0.0, 0.5, 1.0};
        double[] squares = Apply(a, Square);
        double[] sines = Apply(a, Math.Sin);
        Multiplier m = new Multiplier(2.0);
        double[] doubles =  Apply(a, m.Multiply);
    }
}

Instance Function typu delegáta může odkazovat na jakoukoli metodu, která double přebírá argument a vrací double hodnotu.An instance of the Function delegate type can reference any method that takes a double argument and returns a double value. Metoda použije daný Function prvek double[] pro prvky a vrátí výsledek. double[] ApplyThe Apply method applies a given Function to the elements of a double[], returning a double[] with the results. Main V double[]metodě sepoužívákpoužitítřírůznýchfunkcína.ApplyIn the Main method, Apply is used to apply three different functions to a double[].

Delegát může odkazovat buď na statickou metodu (například Square nebo Math.Sin v předchozím příkladu), nebo na metodu m.Multiply instance (například v předchozím příkladu).A delegate can reference either a static method (such as Square or Math.Sin in the previous example) or an instance method (such as m.Multiply in the previous example). Delegát, který odkazuje na metodu instance, také odkazuje na konkrétní objekt a když je metoda instance vyvolána prostřednictvím delegáta, bude this tento objekt ve volání.A delegate that references an instance method also references a particular object, and when the instance method is invoked through the delegate, that object becomes this in the invocation.

Delegáty je také možné vytvořit pomocí anonymních funkcí, což jsou "vložené metody", které jsou vytvářeny průběžně.Delegates can also be created using anonymous functions, which are "inline methods" that are created on the fly. Anonymní funkce mohou zobrazit místní proměnné okolních metod.Anonymous functions can see the local variables of the surrounding methods. Proto je příklad násobitele výše možné napsat snadněji bez použití Multiplier třídy:Thus, the multiplier example above can be written more easily without using a Multiplier class:

double[] doubles =  Apply(a, (double x) => x * 2.0);

Zajímavou a užitečnou vlastností delegáta je, že neznají ani nezáleží na třídě metody, na kterou odkazuje; všechny tyto věci jsou, že odkazovaná metoda má stejné parametry a návratový typ jako delegát.An interesting and useful property of a delegate is that it does not know or care about the class of the method it references; all that matters is that the referenced method has the same parameters and return type as the delegate.

AtributyAttributes

Typy, členy a další entity v C# programu podporují modifikátory, které řídí určité aspekty jejich chování.Types, members, and other entities in a C# program support modifiers that control certain aspects of their behavior. Například přístupnost metody je publicřízena pomocí modifikátorů, protected, internala private .For example, the accessibility of a method is controlled using the public, protected, internal, and private modifiers. C#generalizuje tuto funkci tak, aby uživatelsky definované typy deklarativních informací mohly být připojeny k programovým entitám a načteny v době běhu.C# generalizes this capability such that user-defined types of declarative information can be attached to program entities and retrieved at run-time. Programy určují tyto dodatečné deklarativní informace definováním a použitím atributů.Programs specify this additional declarative information by defining and using attributes.

Následující příklad deklaruje HelpAttribute atribut, který lze umístit do entit programu, aby poskytoval odkazy na jeho přidruženou dokumentaci.The following example declares a HelpAttribute attribute that can be placed on program entities to provide links to their associated documentation.

using System;

public class HelpAttribute: Attribute
{
    string url;
    string topic;

    public HelpAttribute(string url) {
        this.url = url;
    }

    public string Url {
        get { return url; }
    }

    public string Topic {
        get { return topic; }
        set { topic = value; }
    }
}

Všechny třídy atributů jsou odvozeny System.Attribute ze základní třídy poskytnuté .NET Framework.All attribute classes derive from the System.Attribute base class provided by the .NET Framework. Atributy lze použít zadáním jejich názvu spolu s případnými argumenty uvnitř hranatých závorek těsně před přidruženou deklarací.Attributes can be applied by giving their name, along with any arguments, inside square brackets just before the associated declaration. Pokud název atributu končí Attribute, Tato část názvu může být vynechána při odkazování na atribut.If an attribute's name ends in Attribute, that part of the name can be omitted when the attribute is referenced. HelpAttribute Atribut lze například použít následujícím způsobem.For example, the HelpAttribute attribute can be used as follows.

[Help("http://msdn.microsoft.com/.../MyClass.htm")]
public class Widget
{
    [Help("http://msdn.microsoft.com/.../MyClass.htm", Topic = "Display")]
    public void Display(string text) {}
}

Tento HelpAttribute příklad připojí Widget ke tříděaHelpAttribute druhé k metoděvetřídě.DisplayThis example attaches a HelpAttribute to the Widget class and another HelpAttribute to the Display method in the class. Veřejné konstruktory třídy atributu určují informace, které je nutné zadat při připojení atributu k entitě programu.The public constructors of an attribute class control the information that must be provided when the attribute is attached to a program entity. Další informace lze poskytnout odkazem na veřejné vlastnosti pro čtení a zápis třídy atributu (například odkaz na Topic vlastnost dříve).Additional information can be provided by referencing public read-write properties of the attribute class (such as the reference to the Topic property previously).

Následující příklad ukazuje, jak lze načíst informace o atributu pro danou entitu programu v době běhu pomocí reflexe.The following example shows how attribute information for a given program entity can be retrieved at run-time using reflection.

using System;
using System.Reflection;

class Test
{
    static void ShowHelp(MemberInfo member) {
        HelpAttribute a = Attribute.GetCustomAttribute(member,
            typeof(HelpAttribute)) as HelpAttribute;
        if (a == null) {
            Console.WriteLine("No help for {0}", member);
        }
        else {
            Console.WriteLine("Help for {0}:", member);
            Console.WriteLine("  Url={0}, Topic={1}", a.Url, a.Topic);
        }
    }

    static void Main() {
        ShowHelp(typeof(Widget));
        ShowHelp(typeof(Widget).GetMethod("Display"));
    }
}

Pokud je požadován konkrétní atribut prostřednictvím reflexe, konstruktor třídy atributu je vyvolán s informacemi poskytnutými ve zdroji programu a výslednou instancí atributu je vrácen.When a particular attribute is requested through reflection, the constructor for the attribute class is invoked with the information provided in the program source, and the resulting attribute instance is returned. Pokud byly k dispozici další informace prostřednictvím vlastností, jsou tyto vlastnosti nastaveny na zadané hodnoty před vrácením instance atributu.If additional information was provided through properties, those properties are set to the given values before the attribute instance is returned.