WprowadzenieIntroduction

C#(wymawiane "Zobacz Sharp") to prosty, nowoczesny, zorientowany obiektowo i bezpieczny dla typu język programowania.C# (pronounced "See Sharp") is a simple, modern, object-oriented, and type-safe programming language. C#ma swoje elementy główne w rodzinie C i będzie od razu znane programistom języków C, C++i Java.C# has its roots in the C family of languages and will be immediately familiar to C, C++, and Java programmers. C#jest ustandaryzowany przez ECMA International jako standard ECMA-334 i 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# Kompilator firmy Microsoft dla .NET Framework jest zgodny z implementacją obu tych standardów.Microsoft's C# compiler for the .NET Framework is a conforming implementation of both of these standards.

C#jest językiem zorientowanym na obiekt, ale C# dodatkowo obsługuje programowanie zorientowane na składniki .C# is an object-oriented language, but C# further includes support for component-oriented programming. Współczesny projekt oprogramowania jest coraz bardziej oparty na składnikach oprogramowania w postaci samodzielnych i samodzielnych pakietów funkcji.Contemporary software design increasingly relies on software components in the form of self-contained and self-describing packages of functionality. Klucz do takich składników polega na tym, że stanowią one model programowania z właściwościami, metodami i zdarzeniami; mają one atrybuty, które dostarczają deklaracyjne informacje o składniku; i zawierają własną dokumentację.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#Program udostępnia konstrukcje językowe umożliwiające bezpośrednie wsparcie tych koncepcji, C# co sprawia, że jest to bardzo naturalny język, w którym można tworzyć i używać składników oprogramowania.C# provides language constructs to directly support these concepts, making C# a very natural language in which to create and use software components.

Niektóre C# funkcje ułatwiają tworzenie niezawodnych i trwałych aplikacji: Wyrzucanie elementów bezużytecznych automatycznie odzyskuje pamięć zajmowaną przez nieużywane obiekty; Obsługa wyjątków zapewnia strukturalne i rozszerzalne podejście do wykrywania błędów i odzyskiwania. a bezpieczny typ projektu języka sprawia, że nie można odczytać z niezainicjowanych zmiennych, indeksować tablice poza granicami lub wykonywać rzutowania typu unchecked.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#ma ujednolicony system typów.C# has a unified type system. Wszystkie C# typy, w tym typy pierwotne int , doubletakie jak i, dziedziczą object z jednego typu głównego.All C# types, including primitive types such as int and double, inherit from a single root object type. W związku z tym wszystkie typy używają zestawu typowych operacji, a wartości dowolnego typu mogą być przechowywane, transportowane i obsługiwane w spójny sposób.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. Ponadto C# obsługuje zarówno typy odwołań zdefiniowane przez użytkownika, jak i typy wartości, co umożliwia dynamiczne przydzielanie obiektów oraz przechowywanie w wierszu lekkich 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 upewnić C# się, że programy i biblioteki mogą się rozwijać w czasie w zgodnym zakresie, przeznaczenie ma duże znaczenie C#w projekcie wersji .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. W wielu językach programowania jest mało uwagi na ten problem, a w efekcie programy w tych językach są częściej częściej niż to konieczne, gdy są wprowadzane nowsze wersje bibliotek zależnych.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#Zagadnienia dotyczące projektu, które miały bezpośredni wpływ na wersje, obejmują oddzielność virtual i override modyfikatory, reguły rozpoznawania przeciążania metod oraz obsługę jawnych deklaracji elementów członkowskich interfejsu.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.

Pozostała część tego rozdziału zawiera opis najważniejszych funkcji C# języka.The rest of this chapter describes the essential features of the C# language. Chociaż dalsze rozdziały opisują reguły i wyjątki w szczegółowo zorientowanym i niekiedy w sposób matematyczny, ten rozdział dąży do przejrzystości i zwięzłości na koszt kompletności.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. Celem jest zapewnienie czytelnikowi wprowadzenia do języka, który ułatwia pisanie wczesnych programów i odczytywanie dalszych rozdziałów.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" jest tradycyjnie używany do wprowadzania języka programowania.The "Hello, World" program is traditionally used to introduce a programming language. W tym miejscu znajduje C#się w:Here it is in C#:

using System;

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

C#pliki źródłowe mają zwykle rozszerzenie .cspliku.C# source files typically have the file extension .cs. Przy założeniu, że program "Hello, World" jest przechowywany w hello.cspliku, program można skompilować za pomocą kompilatora firmy C# Microsoft przy użyciu wiersza poleceniaAssuming 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

tworzy zestaw wykonywalny o nazwie hello.exe.which produces an executable assembly named hello.exe. Dane wyjściowe generowane przez tę aplikację po jej uruchomieniu toThe output produced by this application when it is run is

Hello, World

Program "Hello, World" rozpoczyna się using od dyrektywy, która odwołuje się do System przestrzeni nazw.The "Hello, World" program starts with a using directive that references the System namespace. Przestrzenie nazw zapewniają hierarchiczną metodę C# organizowania programów i bibliotek.Namespaces provide a hierarchical means of organizing C# programs and libraries. Przestrzenie nazw zawierają typy i inne przestrzenie nazw — System na przykład przestrzeń nazw zawiera wiele typów, takich Console jak Klasa, do której odwołuje się program, oraz liczba innych przestrzeni nazw, IO takich Collectionsjak i.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 Dyrektywa odwołująca się do danej przestrzeni nazw umożliwia niekwalifikowane użycie typów, które są elementami członkowskimi tej przestrzeni nazw.A using directive that references a given namespace enables unqualified use of the types that are members of that namespace. Ze względu using na dyrektywę program może użyć Console.WriteLine jako skrótu dla elementu System.Console.WriteLine.Because of the using directive, the program can use Console.WriteLine as shorthand for System.Console.WriteLine.

Klasa zadeklarowana przez program "Hello, World" ma jeden element członkowski, Metoda o nazwie Main. HelloThe Hello class declared by the "Hello, World" program has a single member, the method named Main. Metoda jest zadeklarowana static z modyfikatorem. MainThe Main method is declared with the static modifier. Chociaż metody wystąpień mogą odwoływać się do określonego wystąpienia obiektu otaczającego za thispomocą słowa kluczowego, metody statyczne działają bez odwołania do określonego obiektu.While instance methods can reference a particular enclosing object instance using the keyword this, static methods operate without reference to a particular object. Zgodnie z Konwencją metoda statyczna Main o nazwie służy jako punkt wejścia programu.By convention, a static method named Main serves as the entry point of a program.

Dane wyjściowe programu są tworzone przez WriteLine metodę Console klasy w System przestrzeni nazw.The output of the program is produced by the WriteLine method of the Console class in the System namespace. Ta klasa jest dostarczana przez .NET Framework biblioteki klas, które domyślnie są przywoływane przez kompilator firmy Microsoft C# .This class is provided by the .NET Framework class libraries, which, by default, are automatically referenced by the Microsoft C# compiler. Należy zauważyć C# , że sama nie ma oddzielnej biblioteki środowiska uruchomieniowego.Note that C# itself does not have a separate runtime library. Zamiast tego .NET Framework jest biblioteką środowiska uruchomieniowego C#programu.Instead, the .NET Framework is the runtime library of C#.

Struktura programuProgram structure

Kluczowe koncepcje organizacyjne C# w programie to programy, przestrzenie nazw, typy, elementy członkowskiei zestawy.The key organizational concepts in C# are programs, namespaces, types, members, and assemblies. C#programy składają się z co najmniej jednego pliku źródłowego.C# programs consist of one or more source files. Programy deklarują typy, które zawierają składowe i mogą być zorganizowane w przestrzenie nazw.Programs declare types, which contain members and can be organized into namespaces. Klasy i interfejsy są przykładami typów.Classes and interfaces are examples of types. Pola, metody, właściwości i zdarzenia są przykładami elementów członkowskich.Fields, methods, properties, and events are examples of members. Gdy C# programy są kompilowane, są fizycznie spakowane do zestawów.When C# programs are compiled, they are physically packaged into assemblies. Zestawy .exe zazwyczaj mają rozszerzenie pliku lub .dll, w zależności od tego, czy implementują aplikacje lub biblioteki.Assemblies typically have the file extension .exe or .dll, depending on whether they implement applications or libraries.

PrzykładThe 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 klasę o Stack nazwie w przestrzeni nazw Acme.Collectionso nazwie.declares a class named Stack in a namespace called Acme.Collections. W pełni kwalifikowana nazwa tej klasy Acme.Collections.Stackto.The fully qualified name of this class is Acme.Collections.Stack. Klasa zawiera kilka elementów członkowskich: pole o nazwie top, dwie metody o Push nazwie Popi i zagnieżdżoną klasę o Entrynazwie.The class contains several members: a field named top, two methods named Push and Pop, and a nested class named Entry. Klasa dodatkowo zawiera trzy elementy członkowskie: pole o nazwie next, pole o nazwie datai Konstruktor. EntryThe Entry class further contains three members: a field named next, a field named data, and a constructor. Przy założeniu, że kod źródłowy przykładu jest przechowywany w pliku acme.cs, wiersz poleceniaAssuming that the source code of the example is stored in the file acme.cs, the command line

csc /t:library acme.cs

kompiluje przykład jako bibliotekę (kod bez Main punktu wejścia) i tworzy zestaw o nazwie. acme.dllcompiles the example as a library (code without a Main entry point) and produces an assembly named acme.dll.

Zestawy zawierają kod wykonywalny w postaci instrukcji języka pośredniego (IL) i informacji symbolicznych w formie metadanych.Assemblies contain executable code in the form of Intermediate Language (IL) instructions, and symbolic information in the form of metadata. Przed wykonaniem kod IL w zestawie jest automatycznie konwertowany na kod specyficzny dla procesora przez kompilator just-in-Time (JIT) środowiska uruchomieniowego języka wspólnego platformy .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.

Ponieważ zestaw jest samoopisującą się jednostką funkcji, która zawiera kod i metadane, nie ma potrzeby stosowania #include dyrektyw i plików nagłówkowych w programie. 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#. Typy publiczne i składowe zawarte w określonym zestawie są udostępniane w C# programie po prostu przez odwołanie się do tego zestawu podczas kompilowania 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. Na przykład ten program używa Acme.Collections.Stack klasy acme.dll z zestawu: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());
    }
}

Jeśli program jest test.csprzechowywany w pliku, po test.cs skompilowaniu acme.dll /r zestawu można odwoływać się za pomocą opcji kompilatora: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

Spowoduje to utworzenie zestawu wykonywalnego test.exeo nazwie, który w przypadku uruchamiania generuje dane wyjściowe:This creates an executable assembly named test.exe, which, when run, produces the output:

100
10
1

C#zezwala na przechowywanie tekstu źródłowego programu w kilku plikach źródłowych.C# permits the source text of a program to be stored in several source files. W przypadku kompilowania programu C# z obsługą wielu plików wszystkie pliki źródłowe są przetwarzane razem, a pliki źródłowe mogą swobodnie odwoływać się do siebie nawzajem — jest to tak samo, jakby wszystkie pliki źródłowe zostały połączone w jeden duży plik przed przetworzeniem.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. Deklaracje przesyłania dalej nie są C# nigdy niewymagane w programie, w związku z czym z kilkoma wyjątkami, zamówienie deklaracji jest nieważne.Forward declarations are never needed in C# because, with very few exceptions, declaration order is insignificant. C#nie ogranicza pliku źródłowego do deklarowania tylko jednego typu publicznego ani nie wymaga, aby nazwa pliku źródłowego była zgodna z typem zadeklarowanym w pliku źródłowym.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 i zmienneTypes and variables

Istnieją dwa rodzaje typów w C#: typy wartości i typy odwołań.There are two kinds of types in C#: value types and reference types. Zmienne typów wartości bezpośrednio zawierają swoje dane, a zmienne typów referencyjnych przechowują odwołania do danych, które są znane jako obiekty.Variables of value types directly contain their data whereas variables of reference types store references to their data, the latter being known as objects. W przypadku typów referencyjnych istnieje możliwość, że dwie zmienne odwołują się do tego samego obiektu, w tym przypadku operacje na jednej zmiennej mają wpływ na obiekt, do którego odwołuje się inna zmienna.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. W przypadku typów wartości zmiennych każda z nich ma własną kopię danych i nie jest możliwe wykonywanie operacji na nich, aby wpływać na inne (z wyjątkiem ref zmiennych i out parametrów).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 wartości są dalej podzielone na typy proste, typy wyliczeniowe, typy strukturi Typy dopuszczające wartość null, a C#typy odwołań są dalej podzielone na typy klas, typy interfejsów, Tablica typyi typy delegatów.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.

Poniższa tabela zawiera omówienie C#systemu typu.The following table provides an overview of C#'s type system.

KategoriaCategory OpisDescription
Typy wartościValue types Typy prosteSimple types Całkowita część ze sbyteznakiem int:, short,,longSigned integral: sbyte, short, int, long
Całka bez byteznaku ushort: uint,,,ulongUnsigned integral: byte, ushort, uint, ulong
Znaki Unicode:charUnicode characters: char
Liczba zmiennoprzecinkowa IEEE float:,doubleIEEE floating point: float, double
Liczba dziesiętna o dużej precyzji:decimalHigh-precision decimal: decimal
TypuboolBoolean: bool
Typy wyliczenioweEnum types Typy formularza zdefiniowane przez użytkownikaenum E {...}User-defined types of the form enum E {...}
Typy strukturStruct types Typy formularza zdefiniowane przez użytkownikastruct S {...}User-defined types of the form struct S {...}
Typy dopuszczające wartości nullNullable types Rozszerzenia wszystkich innych typów wartości z null wartościąExtensions of all other value types with a null value
Typy odwołańReference types Typy klasClass types Ostateczna Klasa bazowa dla wszystkich innych typów:objectUltimate base class of all other types: object
Ciągi Unicode:stringUnicode strings: string
Typy formularza zdefiniowane przez użytkownikaclass C {...}User-defined types of the form class C {...}
Typy interfejsówInterface types Typy formularza zdefiniowane przez użytkownikainterface I {...}User-defined types of the form interface I {...}
Typy tablicArray types Pojedyncze i wielowymiarowe, na przykład int[] iint[,]Single- and multi-dimensional, for example, int[] and int[,]
Typy delegatówDelegate types Typy formularzy zdefiniowane przez użytkownika, np.delegate int D(...)User-defined types of the form e.g. delegate int D(...)

Osiem typów całkowitych zapewnia obsługę 8-bitowych, 16-bitowych, 32-bitowych i 64-bitowych wartości w postaci podpisanej lub niepodpisanej.The eight integral types provide support for 8-bit, 16-bit, 32-bit, and 64-bit values in signed or unsigned form.

Dwa typy zmiennoprzecinkowe, float i double, są reprezentowane przy użyciu 32-bitowej pojedynczej precyzji i 64-bitowe formatów IEEE 754 o podwójnej precyzji.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 jest 128-bitowym typem danych odpowiednim dla obliczeń finansowych i pieniężnych.The decimal type is a 128-bit data type suitable for financial and monetary calculations.

C#Typ jest używany do reprezentowania wartości logicznych — wartości, które true są lub false. boolC#'s bool type is used to represent boolean values—values that are either true or false.

Przetwarzanie znaków i ciągów w C# programie używa kodowania Unicode.Character and string processing in C# uses Unicode encoding. Typ reprezentuje jednostkę kodu UTF-16, string a typ reprezentuje sekwencję jednostek kodu UTF-16. charThe char type represents a UTF-16 code unit, and the string type represents a sequence of UTF-16 code units.

Poniższa tabela zawiera podsumowanie C#typów liczbowych.The following table summarizes C#'s numeric types.

KategoriaCategory BitówBits TypType Zakres/precyzjaRange/Precision
Całkowita ze znakiemSigned integral 88 sbyte -128...127-128...127
1616 short -32768... 32, 767-32,768...32,767
3232 int -2147483648... 2, 147, 483 647-2,147,483,648...2,147,483,647
6464 long -zakresu od... 9, 223, 372, 036, 854, 775,-9,223,372,036,854,775,808...9,223,372,036,854,775,807
Całkowita bez znakuUnsigned 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
Liczba zmiennoprzecinkowaFloating point 3232 float 1,5 × 10 ^ − 45 do 3,4 × 10 ^ 38, 7-cyfrowa precyzja1.5 × 10^−45 to 3.4 × 10^38, 7-digit precision
6464 double 5,0 × 10 ^ − 324 do 1,7 × 10 ^ 308, 15-cyfrowa precyzja5.0 × 10^−324 to 1.7 × 10^308, 15-digit precision
DecimalDecimal 128128 decimal 1,0 × 10 ^ − 28 do 7,9 × 10 ^ 28, 28-cyfrowa precyzja1.0 × 10^−28 to 7.9 × 10^28, 28-digit precision

C#programy używają deklaracji typu do tworzenia nowych typów.C# programs use type declarations to create new types. Deklaracja typu określa nazwę i składowe nowego typu.A type declaration specifies the name and the members of the new type. C#Pięć kategorii typów są definiowane przez użytkownika: typy klas, typy struktur, typy interfejsów, typy wyliczeniowe i typy delegatów.Five of C#'s categories of types are user-definable: class types, struct types, interface types, enum types, and delegate types.

Typ klasy definiuje strukturę danych, która zawiera składowe danych (pola) i składowe funkcji (metody, właściwości i inne).A class type defines a data structure that contains data members (fields) and function members (methods, properties, and others). Typy klas obsługują pojedyncze dziedziczenie i polimorfizm, czyli mechanizmy, w których klasy pochodne mogą poszerzać i specjalizację klas bazowych.Class types support single inheritance and polymorphism, mechanisms whereby derived classes can extend and specialize base classes.

Typ struktury jest podobny do typu klasy w tym, że reprezentuje strukturę z składowymi danych i składowymi funkcji.A struct type is similar to a class type in that it represents a structure with data members and function members. Jednak w przeciwieństwie do klas, struktury są typami wartości i nie wymagają przydziału sterty.However, unlike classes, structs are value types and do not require heap allocation. Typy struktur nie obsługują dziedziczenia określonego przez użytkownika, a wszystkie typy struktur niejawnie dziedziczą objectpo typie.Struct types do not support user-specified inheritance, and all struct types implicitly inherit from type object.

Typ interfejsu definiuje kontrakt jako nazwany zestaw elementów członkowskich funkcji publicznych.An interface type defines a contract as a named set of public function members. Klasa lub struktura implementująca interfejs musi zapewniać implementacje składowych funkcji interfejsu.A class or struct that implements an interface must provide implementations of the interface's function members. Interfejs może dziedziczyć z wielu interfejsów podstawowych, a Klasa lub struktura może zaimplementować wiele interfejsów.An interface may inherit from multiple base interfaces, and a class or struct may implement multiple interfaces.

Typ delegata reprezentuje odwołania do metod z określoną listą parametrów i zwracanym typem.A delegate type represents references to methods with a particular parameter list and return type. Delegaty umożliwiają traktowanie metod jako jednostek, które mogą być przypisane do zmiennych i przekazane jako parametry.Delegates make it possible to treat methods as entities that can be assigned to variables and passed as parameters. Delegaty są podobne do koncepcji wskaźników funkcji, które znajdują się w innych językach, ale w przeciwieństwie do wskaźników funkcji Delegaty są zorientowane obiektowo i są bezpieczne dla typów.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.

Typy klas, struktur, interfejsów i delegatów obsługują ogólne, dzięki czemu można je sparametryzowane z innymi typami.Class, struct, interface and delegate types all support generics, whereby they can be parameterized with other types.

Typ wyliczeniowy jest typem odrębnym o nazwanych stałych.An enum type is a distinct type with named constants. Każdy typ wyliczeniowy ma typ podstawowy, który musi być jednym z ośmiu typów całkowitych.Every enum type has an underlying type, which must be one of the eight integral types. Zestaw wartości typu wyliczeniowego jest taki sam jak zestaw wartości typu podstawowego.The set of values of an enum type is the same as the set of values of the underlying type.

C#obsługuje tablice pojedynczych i wielowymiarowych dowolnego typu.C# supports single- and multi-dimensional arrays of any type. W przeciwieństwie do typów wymienionych powyżej, typy tablicy nie muszą być zadeklarowane przed użyciem.Unlike the types listed above, array types do not have to be declared before they can be used. Zamiast tego typy tablic są konstruowane przez następujące nazwy typu z nawiasami kwadratowymi.Instead, array types are constructed by following a type name with square brackets. Na przykład int[] jest int int inttablicą jednowymiarową, int[,] która jest tablicą dwuwymiarową, i int[][] jest tablicą jednowymiarową tablic jednowymiarowych.For 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 dopuszczające wartość null nie muszą również być zadeklarowane, aby można było ich używać.Nullable types also do not have to be declared before they can be used. Dla każdego typu T wartości niedopuszczających wartości null istnieje odpowiedni typ T?dopuszczający wartość null, który może nullzawierać dodatkowe wartości.For each non-nullable value type T there is a corresponding nullable type T?, which can hold an additional value null. Na przykład int? jest typem, który może zawierać dowolną 32 bitową liczbę całkowitą lub wartość null.For instance, int? is a type that can hold any 32 bit integer or the value null.

C#System typów jest jednorodny tak, że wartość dowolnego typu może być traktowana jako obiekt.C#'s type system is unified such that a value of any type can be treated as an object. Każdy typ C# bezpośrednio lub pośrednio pochodzi od object typu klasy i object jest ostateczną klasą bazową wszystkich typów.Every type in C# directly or indirectly derives from the object class type, and object is the ultimate base class of all types. Wartości typów referencyjnych są traktowane jako obiekty, po prostu wyświetlając wartości jako typ object.Values of reference types are treated as objects simply by viewing the values as type object. Wartości typów wartości są traktowane jako obiekty przez wykonywanie operacji pakowania i rozpakowywania.Values of value types are treated as objects by performing boxing and unboxing operations. W poniższym przykładzie int wartość jest konwertowana na object i z powrotem do 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
    }
}

Gdy wartość typu wartości jest konwertowana na typ object, wystąpienie obiektu, nazywane również "polem", jest przydzielone do przechowywania wartości, a wartość jest kopiowana do tego pola.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. Z drugiej strony, object gdy odwołanie jest rzutowane na typ wartości, jest przeprowadzane sprawdzenie, że przywoływany obiekt jest polem poprawnego typu wartości i, jeśli sprawdzenie zakończy się powodzeniem, wartość w polu jest kopiowana.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#ujednolicony system typów efektywnie oznacza, że typy wartości mogą stać się obiektami "na żądanie".C#'s unified type system effectively means that value types can become objects "on demand." Ze względu na niezjednoczenie bibliotek ogólnego przeznaczenia, które używają object typu, można używać zarówno z typami referencyjnymi, jak i typami wartości.Because of the unification, general-purpose libraries that use type object can be used with both reference types and value types.

W programie istnieją różne rodzaje zmiennych , w C#tym pola, elementy tablicy, zmienne lokalne i parametry.There are several kinds of variables in C#, including fields, array elements, local variables, and parameters. Zmienne reprezentują lokalizacje przechowywania, a Każda zmienna ma typ, który określa, jakie wartości mogą być przechowywane w zmiennej, jak pokazano w poniższej tabeli.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 zmiennejType of Variable Możliwa zawartośćPossible Contents
Typ wartości niedopuszczający wartości nullNon-nullable value type Wartość tego dokładnego typuA value of that exact type
Typ wartości nullNullable value type Wartość null lub wartość tego dokładnego typuA null value or a value of that exact type
object Odwołanie o wartości null, odwołanie do obiektu dowolnego typu odwołania lub odwołanie do wartości opakowanej dowolnego typu wartościA null reference, a reference to an object of any reference type, or a reference to a boxed value of any value type
Typ klasyClass type Odwołanie o wartości null, odwołanie do wystąpienia tego typu klasy lub odwołanie do wystąpienia klasy pochodzącej od tego typu klasy.A 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 interfejsuInterface type Odwołanie o wartości null, odwołanie do wystąpienia typu klasy implementującego ten typ interfejsu lub odwołanie do wartości opakowanej typu wartości implementującej ten typ interfejsuA 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 tablicyArray type Odwołanie o wartości null, odwołanie do wystąpienia tego typu tablicy lub odwołanie do wystąpienia zgodnego typu tablicyA null reference, a reference to an instance of that array type, or a reference to an instance of a compatible array type
Typ delegataDelegate type Odwołanie o wartości null lub odwołanie do wystąpienia tego typu delegataA null reference or a reference to an instance of that delegate type

WyrażeniaExpressions

Wyrażenia są konstruowane na podstawie operandów i operatorów.Expressions are constructed from operands and operators. Operatory wyrażenia wskazują operacje do zastosowania dla operandów.The operators of an expression indicate which operations to apply to the operands. Przykłady operatorów to +, -, *, /i new.Examples of operators include +, -, *, /, and new. Przykładami operandów są literały, pola, zmienne lokalne i wyrażenia.Examples of operands include literals, fields, local variables, and expressions.

Gdy wyrażenie zawiera wiele operatorów pierwszeństwo operatorów określa kolejność, w jakiej są oceniane poszczególne operatory.When an expression contains multiple operators, the precedence of the operators controls the order in which the individual operators are evaluated. Na przykład, wyrażenie x + y * z jest oceniane jako x + (y * z), ponieważ operator * ma wyższy priorytet niż operator +.For example, the expression x + y * z is evaluated as x + (y * z) because the * operator has higher precedence than the + operator.

Większość operatorów może być przeciążona.Most operators can be overloaded. Przeciążanie operatora umożliwia określanie definiowanych przez użytkownika implementacji operatorów dla operacji, w których jeden lub oba operandy mają typ struktury lub klasy zdefiniowanej przez użytkownika.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.

Poniższa tabela podsumowuje C#operatory, wymieniając kategorie operatorów w kolejności od najwyższego do najniższego.The following table summarizes C#'s operators, listing the operator categories in order of precedence from highest to lowest. Operatory w tej samej kategorii mają takie samo pierwszeństwo.Operators in the same category have equal precedence.

KategoriaCategory ExpressionExpression OpisDescription
PodstawowyPrimary x.m Dostęp do elementu członkowskiegoMember access
x(...) Wywołanie metody i delegataMethod and delegate invocation
x[...] Dostęp do tablicy i indeksatoraArray and indexer access
x++ PostinkrementacjaPost-increment
x-- PostdekrementacjaPost-decrement
new T(...) Utworzenie obiektu i delegataObject and delegate creation
new T(...){...} Tworzenie obiektu z inicjatoremObject creation with initializer
new {...} Inicjator obiektu anonimowegoAnonymous object initializer
new T[...] Tworzenie tablicyArray creation
typeof(T) Uzyskaj System.Type obiekt dlaTObtain System.Type object for T
checked(x) Obliczenie wyrażenia w kontekście sprawdzanymEvaluate expression in checked context
unchecked(x) Obliczenie wyrażenia w kontekście niesprawdzanymEvaluate expression in unchecked context
default(T) Uzyskaj wartość domyślną typuTObtain default value of type T
delegate {...} Funkcja anonimowa (metoda anonimowa)Anonymous function (anonymous method)
JednostkUnary +x TożsamośćIdentity
-x NegacjaNegation
!x Negacja logicznaLogical negation
~x Negacja bitowaBitwise negation
++x PreinkrementacjaPre-increment
--x PredekrementacjaPre-decrement
(T)x Jawna konwersja x na typ TExplicitly convert x to type T
await x Asynchronicznie poczekaj na ukończenie xAsynchronously wait for x to complete
MnożeniowyMultiplicative x * y MnożenieMultiplication
x / y DzielenieDivision
x % y ResztaRemainder
DanaAdditive x + y Dodawanie, łączenie ciągów, łączenie delegatówAddition, string concatenation, delegate combination
x - y Odejmowanie, usuwanie delegataSubtraction, delegate removal
ShiftShift x << y Przesunięcie w lewoShift left
x >> y Przesunięcie w prawoShift right
Testowanie relacyjne i typuRelational and type testing x < y Mniejsze niżLess than
x > y Większe niżGreater than
x <= y Mniejsze niż lub równeLess than or equal
x >= y Większe niż lub równeGreater than or equal
x is T true Zwracaj T, jeśli x jest ,false w przeciwnym razieReturn true if x is a T, false otherwise
x as T Zwraca x wartość wpisaną Tjako, null lub x Jeśli nie jestTReturn x typed as T, or null if x is not a T
RównościEquality x == y Równa sięEqual
x != y Nie równa sięNot equal
Logicznego ANDLogical AND x & y Liczba całkowita bitowa, koniunkcja logiczna iInteger bitwise AND, boolean logical AND
Logicznego XORLogical XOR x ^ y Bitowe XOR dla wartości całkowitych, logiczne XOR dla wartości binarnychInteger bitwise XOR, boolean logical XOR
Logicznego ORLogical OR x | y Bitowe OR dla wartości całkowitych, logiczne OR dla wartości binarnychInteger bitwise OR, boolean logical OR
Warunkowego ANDConditional AND x && y Oblicza tylko wtedy, xgdyjest y``trueEvaluates y only if x is true
Warunkowego ORConditional OR x || y Oblicza tylko wtedy, xgdyjest y``falseEvaluates y only if x is false
Łączenia wartości nullNull coalescing x ?? y Jest wynikiem, Abyx w przeciwnym razie null y xEvaluates to y if x is null, to x otherwise
WarunkoweConditional x ? y : z x Daje w y przypadku, gdyz jestx true``falseEvaluates y if x is true, z if x is false
Przypisania lub funkcji anonimowejAssignment or anonymous function x = y PrzypisanieAssignment
x op= y Przypisanie złożone; obsługiwane operatory to *= /= %= += -= <<= >>= &= ^=|=Compound assignment; supported operators are *= /= %= += -= <<= >>= &= ^= |=
(T x) => y Funkcja anonimowa (wyrażenie lambda)Anonymous function (lambda expression)

InstrukcjeStatements

Akcje programu są wyrażane przy użyciu instrukcji.The actions of a program are expressed using statements. C#obsługuje kilka różnych rodzajów instrukcji, które są zdefiniowane w zakresie osadzonych instrukcji.C# supports several different kinds of statements, a number of which are defined in terms of embedded statements.

Blok umożliwia zapisanie wielu instrukcji w kontekstach, w których Pojedyncza instrukcja jest dozwolona.A block permits multiple statements to be written in contexts where a single statement is allowed. Blok składa się z listy instrukcji pisanych między ogranicznikami { i. }A block consists of a list of statements written between the delimiters { and }.

Instrukcje deklaracji są używane do deklarowania zmiennych lokalnych i stałych.Declaration statements are used to declare local variables and constants.

Instrukcje wyrażeń są używane do obliczania wyrażeń.Expression statements are used to evaluate expressions. Wyrażenia, które mogą być używane jako instrukcje, obejmują wywołania metod, alokacje obiektów przy użyciu new operatora, przydziałów używających = i operatorów przypisania złożonego, operacji zwiększania i zmniejszania przy użyciu ++operatory i-- .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.

Instrukcje wyboru są używane do wybierania jednej z wielu możliwych instrukcji do wykonania na podstawie wartości niektórych wyrażeń.Selection statements are used to select one of a number of possible statements for execution based on the value of some expression. W tej grupie są if instrukcje i. switchIn this group are the if and switch statements.

Instrukcje iteracji są używane do wielokrotnego wykonywania osadzonej instrukcji.Iteration statements are used to repeatedly execute an embedded statement. W whiletej grupie są instrukcje, do, for, i. foreachIn this group are the while, do, for, and foreach statements.

Instrukcje skoku są używane do transferowania kontroli.Jump statements are used to transfer control. W tej breakgrupie są instrukcje, continue, goto throw yield , ,i.returnIn this group are the break, continue, goto, throw, return, and yield statements.

try... Instrukcja jest używana do przechwytywania wyjątków, które występują podczas wykonywania bloku, tryi... catch finally Instrukcja służy do określania kodu finalizacji, który jest zawsze wykonywany, niezależnie od tego, czy wystąpił wyjątek, czy nie.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.

Instrukcje checked andunchecked są używane do kontrolowania kontekstu sprawdzania przepełnienia dla operacji arytmetycznych typu całkowitego i konwersji.The checked and unchecked statements are used to control the overflow checking context for integral-type arithmetic operations and conversions.

lock Instrukcja służy do uzyskiwania blokady wzajemnego wykluczania dla danego obiektu, wykonywania instrukcji i zwalniania blokady.The lock statement is used to obtain the mutual-exclusion lock for a given object, execute a statement, and then release the lock.

using Instrukcja służy do uzyskiwania zasobu, wykonywania instrukcji, a następnie usuwania tego zasobu.The using statement is used to obtain a resource, execute a statement, and then dispose of that resource.

Poniżej przedstawiono przykłady poszczególnych rodzajów instrukcjiBelow are examples of each kind of statement

Deklaracje zmiennej lokalnejLocal variable declarations

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

Lokalna deklaracja stałaLocal constant declaration

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

Instrukcja wyrażeniaExpression statement

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

ifMergeif statement

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

switchMergeswitch 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;
    }
}

whileMergewhile statement

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

doMergedo statement

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

forMergefor statement

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

foreachMergeforeach statement

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

breakMergebreak statement

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

continueMergecontinue statement

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

gotoMergegoto statement

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

returnMergereturn statement

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

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

yieldMergeyield 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);
    }
}

throwand try — instrukcjethrow 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!");
    }
}

checkedand unchecked — instrukcjechecked and unchecked statements

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

lockMergelock statement

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

usingMergeusing statement

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

Klasy i obiektyClasses and objects

Klasy są najbardziej podstawowym typem w języku C#.Classes are the most fundamental of C#'s types. Klasa jest strukturą danych, która łączy stan (pola) i akcje (metody i inne elementy członkowskie funkcji) w jednej jednostce.A class is a data structure that combines state (fields) and actions (methods and other function members) in a single unit. Klasa zawiera definicję dla dynamicznie utworzonych wystąpień klasy, znanych również jako obiekty.A class provides a definition for dynamically created instances of the class, also known as objects. Klasy obsługują dziedziczenie i polimorfizm, natomiast mechanizmy, w których klasy pochodne mogą poszerzać i specjalizację klas bazowych.Classes support inheritance and polymorphism, mechanisms whereby derived classes can extend and specialize base classes.

Nowe klasy są tworzone za pomocą deklaracji klasy.New classes are created using class declarations. Deklaracja klasy rozpoczyna się od nagłówka, który określa atrybuty i Modyfikatory klasy, nazwę klasy, klasę bazową (jeśli ma to zastosowanie) i interfejsy zaimplementowane przez klasę.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. Po tym nagłówku następuje treść klasy, która składa się z listy deklaracji elementów członkowskich, które są zapisywane między { ogranicznikami }i.The header is followed by the class body, which consists of a list of member declarations written between the delimiters { and }.

Poniżej znajduje się deklaracja klasy prostej o nazwie 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;
    }
}

Wystąpienia klas są tworzone przy użyciu new operatora, który przydziela pamięć dla nowego wystąpienia, wywołuje konstruktora w celu zainicjowania wystąpienia i zwraca odwołanie do wystąpienia.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. Poniższe instrukcje tworzą dwa Point obiekty i przechowują odwołania do tych obiektów w dwóch zmiennych: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);

Pamięć zajęta przez obiekt jest automatycznie odzyskiwana, gdy obiekt nie jest już używany.The memory occupied by an object is automatically reclaimed when the object is no longer in use. Nie jest to konieczne ani możliwe, aby jawnie cofnąć alokację obiektów w programie C#.It is neither necessary nor possible to explicitly deallocate objects in C#.

MembersMembers

Elementy członkowskie klasy są statycznymi elementami członkowskimi lub wystąpieniami.The members of a class are either static members or instance members. Statyczne składowe należą do klas, a elementy członkowskie wystąpienia należą do obiektów (wystąpień klas).Static members belong to classes, and instance members belong to objects (instances of classes).

Poniższa tabela zawiera omówienie rodzajów elementów członkowskich, które może zawierać Klasa.The following table provides an overview of the kinds of members a class can contain.

CzłonkiemMember OpisDescription
StałeConstants Wartości stałe skojarzone z klasąConstant values associated with the class
PolaFields Zmienne klasyVariables of the class
MetodyMethods Obliczenia i akcje, które mogą być wykonywane przez klasęComputations and actions that can be performed by the class
propertiesProperties Akcje skojarzone z odczytem i pisaniem nazwanych właściwości klasyActions associated with reading and writing named properties of the class
IndeksatoryIndexers Akcje skojarzone z wystąpieniami indeksowania klasy, takimi jak tablicaActions associated with indexing instances of the class like an array
EventsEvents Powiadomienia, które mogą zostać wygenerowane przez klasęNotifications that can be generated by the class
OperatoryOperators Konwersje i operatory wyrażeń obsługiwane przez klasęConversions and expression operators supported by the class
KonstruktorówConstructors Akcje wymagane do zainicjowania wystąpień klasy lub samej klasyActions required to initialize instances of the class or the class itself
DestruktoryDestructors Akcje do wykonania przed trwałe odrzuceniem wystąpień klasyActions to perform before instances of the class are permanently discarded
TypesTypes Zagnieżdżone typy zadeklarowane przez klasęNested types declared by the class

Ułatwienia dostępuAccessibility

Każdy element członkowski klasy ma skojarzoną dostępność, która kontroluje regiony tekstu programu, które mogą uzyskać dostęp do elementu członkowskiego.Each member of a class has an associated accessibility, which controls the regions of program text that are able to access the member. Istnieje pięć możliwych form ułatwień dostępu.There are five possible forms of accessibility. Są one podsumowane w poniższej tabeli.These are summarized in the following table.

Ułatwienia dostępuAccessibility ZnaczenieMeaning
public Dostęp nie jest ograniczonyAccess not limited
protected Dostęp ograniczony do tej klasy lub klas pochodnych od tej klasyAccess limited to this class or classes derived from this class
internal Dostęp ograniczony do tego programuAccess limited to this program
protected internal Dostęp ograniczony do tego programu lub klas pochodzących od tej klasyAccess limited to this program or classes derived from this class
private Dostęp ograniczony do tej klasyAccess limited to this class

Parametry typuType parameters

Definicja klasy może określać zestaw parametrów typu przez poniższą nazwę klasy z nawiasami kątowymi zawierającymi listę nazw parametrów 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 mogą być używane w treści deklaracji klasy do definiowania elementów członkowskich klasy.The type parameters can the be used in the body of the class declarations to define the members of the class. W poniższym przykładzie parametry Pair typu są TFirst i 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 klasy zadeklarowanej do wykonania parametrów typu jest nazywany typem klasy generycznej.A class type that is declared to take type parameters is called a generic class type. Typy struktur, interfejsów i delegatów mogą być również rodzajowe.Struct, interface and delegate types can also be generic.

Gdy używana jest Klasa generyczna, należy podać argumenty typu dla każdego z parametrów 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

Typ ogólny z podanymi argumentami typu, Pair<int,string> jak powyżej, jest nazywany typem skonstruowanym.A generic type with type arguments provided, like Pair<int,string> above, is called a constructed type.

Klas podstawowychBase classes

Deklaracja klasy może określać klasę bazową, postępując według nazwy klasy i parametrów typu z dwukropkiem i nazwą klasy bazowej.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. Pominięcie specyfikacji klasy bazowej jest taka sama jak pochodna typu object.Omitting a base class specification is the same as deriving from type object. Point3D W poniższym przykładzie klasą bazową jest Point, Point a klasą bazową jest 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;
    }
}

Klasa dziedziczy elementy członkowskie swojej klasy bazowej.A class inherits the members of its base class. Dziedziczenie oznacza, że Klasa niejawnie zawiera wszystkie elementy członkowskie swojej klasy podstawowej, z wyjątkiem dla wystąpienia i konstruktorów statycznych i destruktorów klasy bazowej.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. Klasa pochodna może dodawać nowych członków do tych, które dziedziczy, ale nie może usunąć definicji dziedziczonego elementu członkowskiego.A derived class can add new members to those it inherits, but it cannot remove the definition of an inherited member. W poprzednim przykładzie Point3D x dziedziczy pola i y z Point, i każde Point3D wystąpienie zawiera trzy pola, x, y, i 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.

Niejawna konwersja istnieje z typu klasy do dowolnego z jego typów klas podstawowych.An implicit conversion exists from a class type to any of its base class types. W związku z tym zmienna typu klasy może odwoływać się do wystąpienia tej klasy lub wystąpienia dowolnej klasy pochodnej.Therefore, a variable of a class type can reference an instance of that class or an instance of any derived class. Na przykład uwzględniając poprzednie deklaracje klas, zmienna typu Point może odwoływać się do Point lub 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);

PolaFields

Pole jest zmienną, która jest skojarzona z klasą lub wystąpieniem klasy.A field is a variable that is associated with a class or with an instance of a class.

Pole zadeklarowane z static modyfikatorem definiuje pole statyczne.A field declared with the static modifier defines a static field. Pole statyczne identyfikuje dokładnie jedną lokalizację magazynu.A static field identifies exactly one storage location. Niezależnie od tego, ile wystąpień klasy zostało utworzonych, istnieje tylko jedna kopia pola statycznego.No matter how many instances of a class are created, there is only ever one copy of a static field.

Pole zadeklarowane bez static modyfikatora definiuje pole wystąpienia.A field declared without the static modifier defines an instance field. Każde wystąpienie klasy zawiera oddzielną kopię wszystkich pól wystąpienia tej klasy.Every instance of a class contains a separate copy of all the instance fields of that class.

W Color poniższym przykładzie każde wystąpienie klasy ma oddzielną kopię r g Whitepól,, i b Blackwystąpienia Red, ale istnieje tylko jedna kopia,,, Green iBlue pola statyczne: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 pokazano w poprzednim przykładzie pola tylko do odczytu mogą być zadeklarowane za pomocą readonly modyfikatora.As shown in the previous example, read-only fields may be declared with a readonly modifier. Przypisanie do readonly pola może wystąpić tylko jako część deklaracji pola lub konstruktora w tej samej klasie.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 to element członkowski implementujący obliczenia lub akcję, które mogą być wykonywane przez obiekt lub klasę.A method is a member that implements a computation or action that can be performed by an object or class. Metody statyczne są dostępne za pomocą klasy.Static methods are accessed through the class. Metody wystąpienia są dostępne za pomocą wystąpień klasy.Instance methods are accessed through instances of the class.

Metody mają (prawdopodobnie pustą) listę parametrówreprezentujących wartości lub odwołania do zmiennych, które są przenoszone do metody i Typ zwracany, który określa typ wartości obliczanej i zwracanej przez metodę.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. Zwracany typ metody to void , jeśli nie zwraca wartości.A method's return type is void if it does not return a value.

Podobnie jak typy, metody mogą także mieć zestaw parametrów typu, dla których argumenty typu muszą być określone, gdy wywoływana jest metoda.Like types, methods may also have a set of type parameters, for which type arguments must be specified when the method is called. W przeciwieństwie do typów, argumenty typu często można wywnioskować na podstawie argumentów wywołania metody i nie muszą być jawnie określone.Unlike types, the type arguments can often be inferred from the arguments of a method call and need not be explicitly given.

Sygnatura metody musi być unikatowa w klasie, w której metoda jest zadeklarowana.The signature of a method must be unique in the class in which the method is declared. Podpis metody składa się z nazwy metody, liczby parametrów typu oraz liczby, modyfikatorów i typów jego parametrów.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. Sygnatura metody nie zawiera typu zwracanego.The signature of a method does not include the return type.

ParametryParameters

Parametry służą do przekazywania wartości lub odwołań do zmiennych do metod.Parameters are used to pass values or variable references to methods. Parametry metody pobierają rzeczywiste wartości z argumentów , które są określone podczas wywoływania metody.The parameters of a method get their actual values from the arguments that are specified when the method is invoked. Istnieją cztery rodzaje parametrów: parametry wartości, parametry odwołania, parametry wyjściowe i tablice parametrów.There are four kinds of parameters: value parameters, reference parameters, output parameters, and parameter arrays.

Parametr value jest używany do przekazywania parametru wejściowego.A value parameter is used for input parameter passing. Parametr value odnosi się do zmiennej lokalnej, która pobiera jej wartość początkową z argumentu, który został przesłany dla parametru.A value parameter corresponds to a local variable that gets its initial value from the argument that was passed for the parameter. Modyfikacje parametru value nie wpływają na argument, który został przesłany dla parametru.Modifications to a value parameter do not affect the argument that was passed for the parameter.

Parametry wartości mogą być opcjonalne, określając wartość domyślną, aby można było pominąć odpowiednie argumenty.Value parameters can be optional, by specifying a default value so that corresponding arguments can be omitted.

Parametr Reference służy do przekazywania parametrów wejściowych i wyjściowych.A reference parameter is used for both input and output parameter passing. Argument przesłany dla parametru odwołania musi być zmienną i podczas wykonywania metody parametr Reference reprezentuje tę samą lokalizację magazynu co zmienna 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 odwołania jest zadeklarowany z ref modyfikatorem.A reference parameter is declared with the ref modifier. W poniższym przykładzie pokazano sposób użycia ref parametrów.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"
    }
}

Parametr wyjściowy jest używany do przekazywania parametrów wyjściowych.An output parameter is used for output parameter passing. Parametr wyjściowy jest podobny do parametru odwołania, z tą różnicą, że początkowa wartość argumentu dostarczonego przez wywołującego jest nieważna.An output parameter is similar to a reference parameter except that the initial value of the caller-provided argument is unimportant. Parametr wyjściowy jest zadeklarowany z out modyfikatorem.An output parameter is declared with the out modifier. W poniższym przykładzie pokazano sposób użycia out parametrów.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"
    }
}

Tablica parametrów umożliwia przekazanie zmiennej liczbie argumentów do metody.A parameter array permits a variable number of arguments to be passed to a method. Tablica parametrów jest zadeklarowana z params modyfikatorem.A parameter array is declared with the params modifier. Tylko ostatni parametr metody może być tablicą parametrów, a typ tablicy parametrów musi być typem tablicy jednowymiarowej.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 iWriteLine klasy są dobrymi przykładami użycia tablicy parametrów. System.ConsoleThe Write and WriteLine methods of the System.Console class are good examples of parameter array usage. Są one deklarowane w następujący sposób.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) {...}
    ...
}

W metodzie, która używa tablicy parametrów, tablica parametrów zachowuje się dokładnie tak jak zwykły parametr typu tablicy.Within a method that uses a parameter array, the parameter array behaves exactly like a regular parameter of an array type. Jednak w wywołaniu metody z tablicą parametrów możliwe jest przekazanie jednego argumentu typu tablicy parametrów lub dowolnej liczby argumentów typu elementu tablicy parametrów w parametrze.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. W tym drugim przypadku wystąpienie tablicy jest automatycznie tworzone i inicjowane z podanym argumentami.In the latter case, an array instance is automatically created and initialized with the given arguments. Ten przykładThis example

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

jest równoznaczny z zapisem poniżej.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);

Treść metody i zmienne lokalneMethod body and local variables

Treść metody Określa instrukcje do wykonania, gdy metoda jest wywoływana.A method's body specifies the statements to execute when the method is invoked.

Treść metody może deklarować zmienne, które są specyficzne dla wywołania metody.A method body can declare variables that are specific to the invocation of the method. Takie zmienne są nazywane zmiennymi lokalnymi.Such variables are called local variables. Deklaracja zmiennej lokalnej określa nazwę typu, nazwę zmiennej i prawdopodobnie wartość początkową.A local variable declaration specifies a type name, a variable name, and possibly an initial value. Poniższy przykład deklaruje zmienną i lokalną z początkową wartością zero i zmienną j lokalną bez wartości początkowej.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#wymaga, aby zmienna lokalna była przypisana ostatecznie przed uzyskaniem jej wartości.C# requires a local variable to be definitely assigned before its value can be obtained. Na przykład jeśli deklaracja poprzedniej i nie zawierała wartości początkowej, kompilator zgłosi błąd dla kolejnych zastosowań i , ponieważ i nie zostanie on ostatecznie przypisany w tych punktach w programie.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 może użyć return instrukcji do zwrócenia kontroli do obiektu wywołującego.A method can use return statements to return control to its caller. W wyniku zwrócenia void return metody instrukcje nie mogą określać wyrażenia.In a method returning void, return statements cannot specify an expression. W metodzie zwracającejvoidnie, return instrukcje muszą zawierać wyrażenie, które oblicza wartość zwracaną.In a method returning non-void, return statements must include an expression that computes the return value.

Metody static i instanceStatic and instance methods

Metoda zadeklarowana za pomocą static modyfikatora jest metodą statyczną.A method declared with a static modifier is a static method. Metoda statyczna nie działa w konkretnym wystąpieniu i może bezpośrednio uzyskiwać dostęp do statycznych elementów członkowskich.A static method does not operate on a specific instance and can only directly access static members.

Metoda zadeklarowana bez static modyfikatora jest metodą wystąpienia.A method declared without a static modifier is an instance method. Metoda wystąpienia działa w konkretnym wystąpieniu i może uzyskiwać dostęp do elementów członkowskich static i instance.An instance method operates on a specific instance and can access both static and instance members. Wystąpienie, na którym wywołano metodę wystąpienia, można jawnie uzyskać do niego thisdostęp.The instance on which an instance method was invoked can be explicitly accessed as this. Wystąpił błąd podczas odwoływania się this do w metodzie statycznej.It is an error to refer to this in a static method.

Następująca Entity Klasa zawiera elementy członkowskie statyczne i wystąpienia.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żde Entity wystąpienie zawiera numer seryjny (i najprawdopodobniej inne informacje, które nie są wyświetlane w tym miejscu).Each Entity instance contains a serial number (and presumably some other information that is not shown here). Entity Konstruktor (który przypomina metodę wystąpienia) Inicjuje nowe wystąpienie przy użyciu następnego dostępnego numeru seryjnego.The Entity constructor (which is like an instance method) initializes the new instance with the next available serial number. Ponieważ Konstruktor jest członkiem wystąpienia, może uzyskać dostęp zarówno serialNo do pola wystąpienia, nextSerialNo jak i pola statycznego.Because the constructor is an instance member, it is permitted to access both the serialNo instance field and the nextSerialNo static field.

Metody GetNextSerialNo serialNo i SetNextSerialNostaticmogą uzyskać dostęp do pola statycznego,alemożetobyćbłąd,abyuzyskaćbezpośrednidostępdopolawystąpienia.nextSerialNoThe 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.

Poniższy przykład pokazuje użycie Entity klasy.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"
    }
}

Należy zauważyć, SetNextSerialNo że GetNextSerialNo metody i są wywoływane GetSerialNo dla klasy, podczas gdy metoda wystąpienia jest wywoływana w wystąpieniach klasy.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.

Metody wirtualne, przesłonięcia i abstrakcyjneVirtual, override, and abstract methods

Gdy deklaracja metody wystąpienia zawiera virtual modyfikator, metoda jest uznawana za metodę wirtualną.When an instance method declaration includes a virtual modifier, the method is said to be a virtual method. Gdy modyfikator virtual nie jest obecny, metoda jest uznawana za metodę niewirtualną.When no virtual modifier is present, the method is said to be a non-virtual method.

Gdy wywoływana jest metoda wirtualna, typem czasu wykonywania wystąpienia, dla którego odbywa się wywołanie określa rzeczywistą implementację metody do wywołania.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. W wywołaniu metody niewirtualnej Typ czasu kompilacji wystąpienia jest czynnikiem decydującym.In a nonvirtual method invocation, the compile-time type of the instance is the determining factor.

Metoda wirtualna może zostać przesłonięta w klasie pochodnej.A virtual method can be overridden in a derived class. Gdy deklaracja metody wystąpienia zawiera override modyfikator, metoda zastępuje dziedziczną metodę wirtualną z tą samą sygnaturą.When an instance method declaration includes an override modifier, the method overrides an inherited virtual method with the same signature. Podczas gdy deklaracja metody wirtualnej wprowadza nową metodę, Deklaracja metody przesłonięcia specjalizacji istniejącej dziedziczonej metody wirtualnej, dostarczając nową implementację tej 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.

Metoda abstrakcyjna jest metodą wirtualną bez implementacji.An abstract method is a virtual method with no implementation. Metoda abstrakcyjna jest zadeklarowana z abstract modyfikatorem i jest dozwolona tylko w klasie, która również jest abstractzadeklarowana.An abstract method is declared with the abstract modifier and is permitted only in a class that is also declared abstract. Metoda abstrakcyjna musi zostać przesłonięta w każdej nieabstrakcyjnej klasie pochodnej.An abstract method must be overridden in every non-abstract derived class.

Poniższy przykład deklaruje klasę Expressionabstrakcyjną, która reprezentuje węzeł drzewa wyrażenia i trzy Constantklasy pochodne,, VariableReferencei Operation, które implementują węzły drzewa wyrażeń dla stałych, zmienna odwołania i operacje arytmetyczne.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. (Jest to podobne do, ale nie należy mylić z typami drzewa wyrażenia wprowadzonymi w typach drzew wyrażeń).(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");
    }
}

Poprzednie cztery klasy mogą służyć do modelowania wyrażeń arytmetycznych.The previous four classes can be used to model arithmetic expressions. Na przykład przy użyciu wystąpień tych klas wyrażenie x + 3 może być reprezentowane w następujący sposób.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 wystąpienia jest wywoływana w celu obliczenia double danego wyrażenia i utworzenia wartości. Expression EvaluateThe Evaluate method of an Expression instance is invoked to evaluate the given expression and produce a double value. Metoda przyjmuje jako argument a Hashtable , który zawiera nazwy zmiennych (jako klucze wpisów) i wartości (jako wartości wpisów).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 jest wirtualną metodą abstrakcyjną, co oznacza, że nieabstrakcyjne klasy pochodne muszą zastąpić je, aby zapewnić rzeczywistą implementację.The Evaluate method is a virtual abstract method, meaning that non-abstract derived classes must override it to provide an actual implementation.

Constant ImplementacjapoprostuEvaluate zwraca przechowywaną stałą.A Constant's implementation of Evaluate simply returns the stored constant. Implementacja VariableReferenceprogramu wyszukuje nazwę zmiennej w elemencie Hashtable i zwraca wartość wynikową.A VariableReference's implementation looks up the variable name in the hashtable and returns the resulting value. Implementacja najpierw szacuje lewy i prawy operand (cyklicznie wywołując ich Evaluate metody), a następnie wykonuje daną operację arytmetyczną. OperationAn Operation's implementation first evaluates the left and right operands (by recursively invoking their Evaluate methods) and then performs the given arithmetic operation.

Poniższy program używa Expression klas do obliczenia wyrażenia x * (y + 2) pod kątem różnych wartości x i 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"
    }
}

Przeciążanie metodyMethod overloading

Przeciążanie metod pozwala wielu metodom w tej samej klasie mieć taką samą nazwę, o ile mają unikatowe podpisy.Method overloading permits multiple methods in the same class to have the same name as long as they have unique signatures. Podczas kompilowania wywołania przeciążonej metody kompilator używa rozdzielczości przeciążenia do określenia konkretnej metody do wywołania.When compiling an invocation of an overloaded method, the compiler uses overload resolution to determine the specific method to invoke. Rozpoznanie przeciążenia umożliwia znalezienie jednej metody, która najlepiej pasuje do argumentów lub zgłasza błąd, jeśli nie można znaleźć pojedynczego najlepszego dopasowania.Overload resolution finds the one method that best matches the arguments or reports an error if no single best match can be found. W poniższym przykładzie przedstawiono sposób rozwiązywania przeciążenia.The following example shows overload resolution in effect. Komentarz dla każdego wywołania Main metody pokazuje, która metoda jest faktycznie wywoływana.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 pokazano w przykładzie, dana metoda może być zawsze wybierana przez jawne rzutowanie argumentów na dokładne typy parametrów i/lub jawne dostarczenie argumentów 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.

Inne elementy członkowskie funkcjiOther function members

Elementy członkowskie, które zawierają kod wykonywalny, są określane zbiorczo jako elementy członkowskie klasy.Members that contain executable code are collectively known as the function members of a class. W poprzedniej sekcji opisano metody, które są podstawowym rodzajem elementów członkowskich funkcji.The preceding section describes methods, which are the primary kind of function members. W tej sekcji opisano inne rodzaje składowych funkcji obsługiwane przez C#: konstruktory, właściwości, indeksatory, zdarzenia, operatory i destruktory.This section describes the other kinds of function members supported by C#: constructors, properties, indexers, events, operators, and destructors.

Poniższy kod przedstawia klasę generyczną o nazwie List<T>, która implementuje rozwijaną listę obiektów.The following code shows a generic class called List<T>, which implements a growable list of objects. Klasa zawiera kilka przykładów typowych rodzajów elementów członkowskich funkcji.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);
    }
}

KonstruktorówConstructors

C#obsługuje zarówno konstruktory wystąpienia, jak i statyczne.C# supports both instance and static constructors. Konstruktor wystąpienia jest członkiem, który implementuje akcje wymagane do zainicjowania wystąpienia klasy.An instance constructor is a member that implements the actions required to initialize an instance of a class. Statyczny Konstruktor jest członkiem, który implementuje akcje wymagane do zainicjowania samej klasy podczas pierwszego ładowania.A static constructor is a member that implements the actions required to initialize a class itself when it is first loaded.

Konstruktor jest zadeklarowany jak metoda bez zwracanego typu i o takiej samej nazwie jak zawierająca klasy.A constructor is declared like a method with no return type and the same name as the containing class. Jeśli deklaracja konstruktora zawiera static modyfikator, deklaruje Konstruktor statyczny.If a constructor declaration includes a static modifier, it declares a static constructor. W przeciwnym razie deklaruje Konstruktor wystąpienia.Otherwise, it declares an instance constructor.

Konstruktory wystąpień mogą być przeciążone.Instance constructors can be overloaded. Na przykład List<T> Klasa deklaruje dwa konstruktory wystąpień, jeden bez parametrów i jeden, który int pobiera parametr.For example, the List<T> class declares two instance constructors, one with no parameters and one that takes an int parameter. Konstruktory wystąpień są wywoływane przy new użyciu operatora.Instance constructors are invoked using the new operator. Poniższe instrukcje przydzielą List<string> dwa wystąpienia przy użyciu każdego konstruktora List klasy.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);

W przeciwieństwie do innych elementów członkowskich, konstruktory wystąpień nie są dziedziczone, a Klasa nie ma konstruktorów wystąpień innych niż zadeklarowane w klasie.Unlike other members, instance constructors are not inherited, and a class has no instance constructors other than those actually declared in the class. Jeśli nie podano konstruktora wystąpienia dla klasy, zostanie automatycznie podana pusta wartość bez parametrów.If no instance constructor is supplied for a class, then an empty one with no parameters is automatically provided.

propertiesProperties

Właściwości są naturalnym rozszerzeniem pól.Properties are a natural extension of fields. Oba są nazwanymi członkami ze skojarzonymi typami, a składnia dostępu do pól i właściwości jest taka sama.Both are named members with associated types, and the syntax for accessing fields and properties is the same. Jednak w przeciwieństwie do pól właściwości nie oznacza lokalizacji magazynu.However, unlike fields, properties do not denote storage locations. Zamiast tego właściwości mają metody dostępu określające instrukcje, które mają być wykonywane, gdy ich wartości są odczytywane lub zapisywane.Instead, properties have accessors that specify the statements to be executed when their values are read or written.

Właściwość jest zadeklarowana jako pole, z tą różnicą, że deklaracja kończy get się akcesorem i/ set lub akcesorem zapisanym { między ogranicznikami i } zamiast kończyć się średnikiem.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. Właściwość, która get ma zarówno akcesor, set jak i akcesora get , jest właściwością do odczytu i zapisu, właściwość, która ma tylko metodę dostępu, jest właściwością tylko do odczytui właściwość, która set ma tylko metodę dostępu, jest Właściwość tylko do zapisu.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.

Metoda get dostępu odpowiada metodzie bez parametrów z wartością zwracaną typu właściwości.A get accessor corresponds to a parameterless method with a return value of the property type. Poza elementem docelowym przypisania, gdy właściwość jest przywoływana w wyrażeniu, get metoda dostępu do właściwości jest wywoływana w celu obliczenia wartości właściwości.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.

Metoda dostępu odpowiada metodzie z pojedynczym parametrem o nazwie value i bez zwracanego typu. setA set accessor corresponds to a method with a single parameter named value and no return type. Gdy właściwość jest przywoływana jako element docelowy przypisania lub jako operand ++ lub --, set metoda dostępu jest wywoływana z argumentem, który dostarcza nową wartość.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.

Klasa deklaruje dwie Count właściwości i Capacity, które są tylko do odczytu i odczytu i zapisu. List<T>The List<T> class declares two properties, Count and Capacity, which are read-only and read-write, respectively. Poniżej przedstawiono przykład użycia tych właściwości.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

Podobnie jak pola i metody, C# obsługuje zarówno właściwości wystąpienia, jak i właściwości statyczne.Similar to fields and methods, C# supports both instance properties and static properties. Właściwości statyczne są zadeklarowane za static pomocą modyfikatora, a właściwości wystąpienia są deklarowane bez użycia.Static properties are declared with the static modifier, and instance properties are declared without it.

Metody dostępu właściwości mogą być wirtualne.The accessor(s) of a property can be virtual. Gdy Deklaracja właściwości zawiera virtualmodyfikator, abstractlub override , ma zastosowanie do akcesorów właściwości.When a property declaration includes a virtual, abstract, or override modifier, it applies to the accessor(s) of the property.

IndeksatoryIndexers

Indeksator jest członkiem, który umożliwia indeksowanie obiektów w taki sam sposób jak w przypadku tablicy.An indexer is a member that enables objects to be indexed in the same way as an array. Indeksator jest zadeklarowany jak właściwość, z tą różnicą, że this po nazwie składowej następuje lista parametrów zapisywana między [ ogranicznikami i ].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 są dostępne w metodach dostępu indeksatora.The parameters are available in the accessor(s) of the indexer. Podobnie jak w przypadku właściwości, indeksatory mogą być tylko do odczytu i zapisu, tylko do odczytu i do zapisu, a Akcesory dla indeksatora mogą być wirtualne.Similar to properties, indexers can be read-write, read-only, and write-only, and the accessor(s) of an indexer can be virtual.

Klasa deklaruje pojedynczy indeksator do odczytu i zapisu, który int pobiera parametr. ListThe List class declares a single read-write indexer that takes an int parameter. Indeksator umożliwia indeksowanie List wystąpień z int wartościami.The indexer makes it possible to index List instances with int values. Na przykład:For 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();
}

Indeksatory mogą być przeciążone, co oznacza, że Klasa może deklarować wiele indeksatorów, o ile liczba lub typy ich parametrów różnią się.Indexers can be overloaded, meaning that a class can declare multiple indexers as long as the number or types of their parameters differ.

EventsEvents

Zdarzenie jest członkiem, który umożliwia klasy lub obiektowi dostarczanie powiadomień.An event is a member that enables a class or object to provide notifications. Zdarzenie jest zadeklarowane jak pole, z tą różnicą, że event deklaracja zawiera słowo kluczowe i typ musi być typem delegata.An event is declared like a field except that the declaration includes an event keyword and the type must be a delegate type.

W obrębie klasy, która deklaruje element członkowski zdarzenia, zdarzenie zachowuje się podobnie jak pole typu delegata (pod warunkiem, że zdarzenie nie jest abstrakcyjne i nie deklaruje metod dostępu).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). W polu jest przechowywane odwołanie do delegata, który reprezentuje programy obsługi zdarzeń, które zostały dodane do zdarzenia.The field stores a reference to a delegate that represents the event handlers that have been added to the event. Jeśli nie ma żadnych dojść do zdarzeń, pole jest null.If no event handles are present, the field is null.

Klasa deklaruje pojedynczy element członkowski zdarzenia o Changednazwie, który wskazuje, że dodano nowy element do listy. 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. Zdarzenie jest zgłaszane OnChanged przez metodę wirtualną, która najpierw sprawdza, czy zdarzenie jest null (oznacza, że nie ma żadnych programów obsługi). ChangedThe Changed event is raised by the OnChanged virtual method, which first checks whether the event is null (meaning that no handlers are present). Pojęcie związane z wywoływaniem zdarzenia jest dokładnie równoważne do wywołania delegata reprezentowanego przez zdarzenie, co oznacza, że nie istnieją żadne specjalne konstrukcje języka do wywoływania zdarzeń.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.

Klienci reagują na zdarzenia za poorednictwem programów obsługi zdarzeń.Clients react to events through event handlers. Procedury obsługi zdarzeń są dołączane += przy użyciu operatora i usuwane -= przy użyciu operatora.Event handlers are attached using the += operator and removed using the -= operator. Poniższy przykład dołącza procedurę obsługi zdarzeń do Changed zdarzenia. 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"
    }
}

W przypadku zaawansowanych scenariuszy, w których wymagana jest kontrola bazowego magazynu zdarzenia, deklaracja zdarzenia może jawnie dostarczyć add i remove akcesorów, które set są nieco podobne do metody dostępu do właściwości.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.

OperatoryOperators

Operator jest członkiem, który definiuje znaczenie zastosowania określonego operatora wyrażenia do wystąpienia klasy.An operator is a member that defines the meaning of applying a particular expression operator to instances of a class. Można zdefiniować trzy rodzaje operatorów: operatory jednoargumentowe, operatory binarne i operatory konwersji.Three kinds of operators can be defined: unary operators, binary operators, and conversion operators. Wszystkie operatory muszą być zadeklarowane public jako statici.All operators must be declared as public and static.

Klasa deklaruje dwa operator== operatory i operator!=i w ten sposób daje nowe znaczenie dla wyrażeń, które stosują te List operatory do wystąpień. 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. W tym celu operatory definiują równość dwóch List<T> wystąpień w porównaniu z poszczególnymi obiektami zawartymi Equals przy użyciu metod.Specifically, the operators define equality of two List<T> instances as comparing each of the contained objects using their Equals methods. Poniższy przykład używa == operatora do porównywania dwóch List<int> wystąpień.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"
    }
}

Pierwsze Console.WriteLine dane wyjściowe True , ponieważ dwie listy zawierają tę samą liczbę obiektów z tymi samymi wartościami w tej samej kolejności.The first Console.WriteLine outputs True because the two lists contain the same number of objects with the same values in the same order. Console.WriteLine False List<int> Nie zdefiniowano operator==, pierwsze miałoby wynik, ponieważ a i odwołuje się do b różnych wystąpień. 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 jest członkiem, który implementuje akcje wymagane do zadestruktorowania wystąpienia klasy.A destructor is a member that implements the actions required to destruct an instance of a class. Destruktory nie mogą mieć parametrów, nie mogą mieć modyfikatorów dostępności i nie mogą być wywoływane jawnie.Destructors cannot have parameters, they cannot have accessibility modifiers, and they cannot be invoked explicitly. Destruktor dla wystąpienia jest wywoływany automatycznie podczas wyrzucania elementów bezużytecznych.The destructor for an instance is invoked automatically during garbage collection.

Moduł wyrzucania elementów bezużytecznych jest dozwolony w przypadku podejmowania decyzji o zbieraniu obiektów i destruktorów uruchamiania.The garbage collector is allowed wide latitude in deciding when to collect objects and run destructors. W odróżnieniu od czasu wywołania destruktorów nie jest deterministyczna, a destruktory mogą być wykonywane na dowolnym wątku.Specifically, the timing of destructor invocations is not deterministic, and destructors may be executed on any thread. Z tych i innych powodów klasy powinny implementować destruktory tylko wtedy, gdy żadne inne rozwiązania nie są możliwe.For these and other reasons, classes should implement destructors only when no other solutions are feasible.

using Instrukcja zawiera lepsze podejście do niszczenia obiektów.The using statement provides a better approach to object destruction.

StrukturyStructs

Podobnie jak klasy, struktury są strukturami danych, które mogą zawierać składowe danych i składowe funkcji, ale w przeciwieństwie do klas, struktury są typami wartości i nie wymagają przydziału sterty.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. Zmienna typu struktury bezpośrednio przechowuje dane struktury, podczas gdy zmienna typu klasy przechowuje odwołanie do obiektu przydzielanego dynamicznie.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 struktur nie obsługują dziedziczenia określonego przez użytkownika, a wszystkie typy struktur niejawnie dziedziczą objectpo typie.Struct types do not support user-specified inheritance, and all struct types implicitly inherit from type object.

Struktury są szczególnie przydatne w przypadku małych struktur danych, które mają semantykę wartości.Structs are particularly useful for small data structures that have value semantics. Liczby zespolone, punkty w układzie współrzędnych lub pary klucz-wartość w słowniku są wszystkimi dobrymi przykładami struktur.Complex numbers, points in a coordinate system, or key-value pairs in a dictionary are all good examples of structs. Użycie struktur zamiast klas dla małych struktur danych może spowodować znaczną różnicę liczby alokacji pamięci wykonywanej przez aplikację.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. Na przykład następujący program tworzy i Inicjuje tablicę z 100 punktów.For example, the following program creates and initializes an array of 100 points. Z Point zaimplementowaną klasą, 101 oddzielnych obiektów są tworzone wystąpienia — jeden dla tablicy i jeden dla elementów 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);
    }
}

Alternatywą jest tworzenie 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;
    }
}

Teraz zostanie utworzony tylko jeden obiekt — jeden dla tablicy — i Point wystąpienia są przechowywane w wierszu tablicy.Now, only one object is instantiated—the one for the array—and the Point instances are stored in-line in the array.

Konstruktory struktury są wywoływane z new operatorem, ale nie oznacza to, że pamięć jest przyznana.Struct constructors are invoked with the new operator, but that does not imply that memory is being allocated. Zamiast dynamicznie przydzielać obiektu i zwracać odwołanie do niego, Konstruktor struktury po prostu zwraca wartość struktury (zazwyczaj w tymczasowej lokalizacji na stosie), a następnie ta wartość jest kopiowana w razie potrzeby.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.

Klasy, istnieje możliwość, że dwie zmienne odwołują się do tego samego obiektu, a tym samym możliwe dla operacji na jednej zmiennej, aby wpływać na obiekt, do którego odwołuje się inna zmienna.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. W przypadku struktur zmienne każda z nich ma własną kopię danych i nie jest możliwe wykonywanie operacji na nich, aby wpływać na inne.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. Na przykład dane wyjściowe generowane przez Poniższy fragment kodu zależą od tego, czy Point jest klasą czy strukturą.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);

Jeśli Point jest klasą, dane wyjściowe są 20 spowodowane a b tym samym obiektem.If Point is a class, the output is 20 because a and b reference the same object. Jeśli Point jest strukturą, dane wyjściowe wynikają 10 z faktu a , b że przypisanie do tworzy kopię wartości i ta kopia nie ma wpływ na kolejne przypisanie do 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.

Poprzedni przykład wyróżnia dwa ograniczenia struktur.The previous example highlights two of the limitations of structs. Najpierw kopiowanie całej struktury jest zwykle mniej wydajne niż kopiowanie odwołania do obiektu, dlatego przypisanie i wartość przekazywanie parametrów mogą być bardziej kosztowne z strukturami niż w przypadku typów referencyjnych.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. Po drugie, z ref wyjątkiem out parametrów i, nie jest możliwe tworzenie odwołań do struktur, które wywołują zasady ich użycia w wielu sytuacjach.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.

TabliceArrays

Tablica to struktura danych zawierająca pewną liczbę zmiennych, do których dostęp jest uzyskiwany za pomocą obliczonych indeksów.An array is a data structure that contains a number of variables that are accessed through computed indices. Zmienne zawarte w tablicy, nazywane również elementami tablicy, są tego samego typu, a ten typ jest nazywany typem elementu tablicy.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 tablic są typami odwołań, a deklaracja zmiennej tablicowej po prostu ustawia miejsce na odwołanie do wystąpienia tablicy.Array types are reference types, and the declaration of an array variable simply sets aside space for a reference to an array instance. Rzeczywiste wystąpienia tablicy są tworzone dynamicznie w czasie wykonywania przy użyciu new operatora.Actual array instances are created dynamically at run-time using the new operator. Operacja określa długość nowego wystąpienia tablicy, które jest następnie naprawione dla okresu istnienia wystąpienia. newThe new operation specifies the length of the new array instance, which is then fixed for the lifetime of the instance. Indeksy elementów z zakresu tablicy od 0 do. Length - 1The indices of the elements of an array range from 0 to Length - 1. Operator automatycznie inicjuje elementy tablicy do ich wartości domyślnych, które na przykład są równe zero dla wszystkich typów liczbowych i null dla wszystkich typów odwołań. 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.

Poniższy przykład tworzy tablicę int elementów, Inicjuje tablicę i drukuje zawartość tablicy.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]);
        }
    }
}

Ten przykład tworzy i działa na tablicy jednowymiarowej.This example creates and operates on a single-dimensional array. C#obsługuje również tablicewielowymiarowe.C# also supports multi-dimensional arrays. Liczba wymiarów typu tablicy, znana również jako ranga typu tablicy, jest taka, a liczba przecinkiów zapisywana między nawiasami kwadratowymi typu tablicy.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. Poniższy przykład przydziela jednowymiarową, dwuwymiarową i trójwymiarową tablicę.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];

Tablica zawiera 10 elementów a2 , tablica zawiera 50 (10 × 5 a3 ) elementów, a tablica zawiera 100 (10 × 5 x 2) elementów. 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 tablicy może być dowolnego typu, łącznie z typem tablicy.The element type of an array can be any type, including an array type. Tablica z elementami typu tablicy jest czasami nazywana tablicą nieregularną , ponieważ długości tablic elementów nie wszystkie muszą być takie same.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. Poniższy przykład alokuje tablicę inttablic: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];

Pierwszy wiersz tworzy tablicę z trzema elementami, każdy typ int[] i każdy z początkową nullwartością.The first line creates an array with three elements, each of type int[] and each with an initial value of null. Kolejne wiersze inicjują następnie trzy elementy z odwołaniami do poszczególnych wystąpień tablicy o różnej długości.The subsequent lines then initialize the three elements with references to individual array instances of varying lengths.

Operator zezwala na określenie wartości początkowych elementów tablicy przy użyciu inicjatora tablicy, który jest listą wyrażeń pisanych ogranicznikami { i. } 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 }. Poniższy przykład przydziela i inicjuje int[] z trzema elementami.The following example allocates and initializes an int[] with three elements.

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

Należy zauważyć, że długość tablicy jest wywnioskowana na podstawie liczby wyrażeń między { i. }Note that the length of the array is inferred from the number of expressions between { and }. Deklaracje zmiennej lokalnej i pola mogą być skrócone w taki sposób, aby nie trzeba było przestawiać tego typu tablicy.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 poprzednie przykłady są równoważne z następującymi: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;

InterfejsyInterfaces

Interfejs definiuje kontrakt, który może być zaimplementowany przez klasy i struktury.An interface defines a contract that can be implemented by classes and structs. Interfejs może zawierać metody, właściwości, zdarzenia i indeksatory.An interface can contain methods, properties, events, and indexers. Interfejs nie dostarcza implementacji elementów członkowskich, które definiuje — tylko określa elementy członkowskie, które muszą być dostarczone przez klasy lub struktury, które implementują interfejs.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.

Interfejsy mogą wykorzystywać wielokrotne dziedziczenie.Interfaces may employ multiple inheritance. W poniższym przykładzie interfejs IComboBox dziedziczy z obu ITextBox i 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 {}

Klasy i struktury mogą implementować wiele interfejsów.Classes and structs can implement multiple interfaces. W poniższym przykładzie Klasa EditBox implementuje zarówno IControl , jak i IDataBound.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) {...}
}

Gdy Klasa lub struktura implementuje określony interfejs, wystąpienia tej klasy lub struktury mogą być niejawnie konwertowane na typ tego interfejsu.When a class or struct implements a particular interface, instances of that class or struct can be implicitly converted to that interface type. Na przykład:For example

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

W przypadkach, gdy wystąpienie nie jest statycznie znane do implementacji określonego interfejsu, można użyć rzutowania typu dynamicznego.In cases where an instance is not statically known to implement a particular interface, dynamic type casts can be used. Na przykład następujące instrukcje używają rzutowania typu dynamicznego do uzyskiwania implementacji obiektu IControl i IDataBound interfejsu.For example, the following statements use dynamic type casts to obtain an object's IControl and IDataBound interface implementations. Ponieważ rzeczywisty typ obiektu to EditBox, Rzutowanie powiedzie się.Because the actual type of the object is EditBox, the casts succeed.

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

W EditBox poprzedniej public klasie Paint Metoda IControl IDataBound z interfejsu i Metodazinterfejsusąimplementowanezapomocąelementówczłonkowskich.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#obsługuje również jawne implementacje elementu członkowskiego interfejsu, za pomocą którego Klasa lub struktura może uniknąć publictworzenia elementów członkowskich.C# also supports explicit interface member implementations, using which the class or struct can avoid making the members public. Implementacja jawnego elementu członkowskiego interfejsu jest zapisywana przy użyciu w pełni kwalifikowanej nazwy elementu członkowskiego interfejsu.An explicit interface member implementation is written using the fully qualified interface member name. Na przykład EditBox Klasa może IControl.Paint zaimplementować metody i IDataBound.Bind przy użyciu jawnych implementacji elementu członkowskiego interfejsu w następujący sposób.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) {...}
}

Dostęp do jawnych elementów członkowskich interfejsu można uzyskać tylko za pośrednictwem typu interfejsu.Explicit interface members can only be accessed via the interface type. Na przykład implementacja IControl.Paint dostarczonych przez poprzednią EditBox klasę może być EditBox wywoływana tylko przez pierwsze IControl przekonwertowanie odwołania do typu interfejsu.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

WyliczeniaEnums

Typ wyliczeniowy to odrębny typ wartości zawierający zestaw nazwanych stałych.An enum type is a distinct value type with a set of named constants. Poniższy przykład deklaruje i używa typu wyliczeniowego Color o nazwie z trzema Redstałymi wartościami Blue,, Greeni.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żdy typ wyliczeniowy ma odpowiedni typ całkowity nazywany typem podstawowym typu wyliczeniowego.Each enum type has a corresponding integral type called the underlying type of the enum type. Typ wyliczeniowy, który nie deklaruje jawnie typu podstawowego, ma typ intpodstawowy.An enum type that does not explicitly declare an underlying type has an underlying type of int. Format magazynu typu wyliczeniowego i zakres możliwych wartości są określane przez jego typ podstawowy.An enum type's storage format and range of possible values are determined by its underlying type. Zbiór wartości, dla których można zastosować typ wyliczeniowy, nie jest ograniczony przez elementy członkowskie wyliczenia.The set of values that an enum type can take on is not limited by its enum members. W szczególności każda wartość typu podstawowego wyliczenia może być rzutowana na typ wyliczeniowy i jest unikatową prawidłową wartością tego typu wyliczeniowego.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.

Poniższy przykład deklaruje typ wyliczeniowy o nazwie Alignment z sbytetypem podstawowym.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 pokazano w poprzednim przykładzie, Deklaracja elementu członkowskiego wyliczenia może zawierać wyrażenie stałe, które określa wartość elementu członkowskiego.As shown by the previous example, an enum member declaration can include a constant expression that specifies the value of the member. Wartość stała dla każdego elementu członkowskiego wyliczenia musi znajdować się w zakresie bazowego typu wyliczenia.The constant value for each enum member must be in the range of the underlying type of the enum. Jeśli deklaracja elementu członkowskiego wyliczenia nie określa jawnie wartości, element członkowski otrzymuje wartość zero (jeśli jest to pierwszy element członkowski typu enum) lub wartość w postaci jednokrotnie poprzedzającej składową wyliczenia plus jeden.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.

Wartości wyliczeniowe mogą być konwertowane na wartości całkowite i odwrotnie przy użyciu rzutowania typu.Enum values can be converted to integral values and vice versa using type casts. Na przykład:For example

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

Wartość domyślna dowolnego typu wyliczeniowego jest wartością całkowitą zero przekonwertowaną na typ wyliczeniowy.The default value of any enum type is the integral value zero converted to the enum type. W przypadkach, gdy zmienne są automatycznie inicjowane do wartości domyślnej, jest to wartość nadana zmiennym typów wyliczeniowych.In cases where variables are automatically initialized to a default value, this is the value given to variables of enum types. Aby wartość domyślna typu wyliczeniowego była łatwo dostępna, literał 0 niejawnie konwertowany na dowolny typ wyliczeniowy.In order for the default value of an enum type to be easily available, the literal 0 implicitly converts to any enum type. W ten sposób można używać następujących sposobów.Thus, the following is permitted.

Color c = 0;

DelegatyDelegates

Typ delegata reprezentuje odwołania do metod z określoną listą parametrów i zwracanym typem.A delegate type represents references to methods with a particular parameter list and return type. Delegaty umożliwiają traktowanie metod jako jednostek, które mogą być przypisane do zmiennych i przekazane jako parametry.Delegates make it possible to treat methods as entities that can be assigned to variables and passed as parameters. Delegaty są podobne do koncepcji wskaźników funkcji, które znajdują się w innych językach, ale w przeciwieństwie do wskaźników funkcji Delegaty są zorientowane obiektowo i są bezpieczne dla typów.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.

Poniższy przykład deklaruje i używa typu delegata o Functionnazwie.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);
    }
}

Wystąpienie Function typu delegata może odwoływać się do dowolnej metody, która double przyjmuje argument i zwraca double wartość.An instance of the Function delegate type can reference any method that takes a double argument and returns a double value. Metoda odnosi Function się do elementów a double[], zwracając double[] wynik. ApplyThe Apply method applies a given Function to the elements of a double[], returning a double[] with the results. Metoda jest używana do zastosowania double[]trzech różnych funkcji do. Apply MainIn the Main method, Apply is used to apply three different functions to a double[].

Delegat może odwoływać się do metody statycznej (takiej Square jak Math.Sin lub w poprzednim przykładzie) lub metody m.Multiply wystąpienia (na przykład w poprzednim przykładzie).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). Delegat, który odwołuje się do metody wystąpienia, odwołuje się również do określonego obiektu i gdy metoda wystąpienia jest wywoływana za pomocą delegata this , ten obiekt zostaje w wywołaniu.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.

Delegatów można także tworzyć za pomocą funkcji anonimowych, które są "metodami wbudowanymi", które są tworzone na bieżąco.Delegates can also be created using anonymous functions, which are "inline methods" that are created on the fly. Funkcje anonimowe mogą zobaczyć zmienne lokalne otaczających metod.Anonymous functions can see the local variables of the surrounding methods. W ten sposób przykład mnożnika można napisać łatwiej, bez użycia Multiplier klasy:Thus, the multiplier example above can be written more easily without using a Multiplier class:

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

Interesująca i przydatna właściwość delegata polega na tym, że nie wie ani nie posługuje się klasą metody, do której się odwołuje; wszystkie te kwestie polegają na tym, że metoda przywoływana ma te same parametry i zwracany typ jako delegat.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.

AtrybutyAttributes

Typy, elementy członkowskie i inne jednostki w C# programie obsługują Modyfikatory kontrolujące pewne aspekty ich zachowania.Types, members, and other entities in a C# program support modifiers that control certain aspects of their behavior. Na przykład dostępność metody jest publickontrolowana za pomocą modyfikatorów, protected, internali private .For example, the accessibility of a method is controlled using the public, protected, internal, and private modifiers. C#służy do uogólniania tej funkcji w taki sposób, aby typy informacji deklaratywnych zdefiniowanych przez użytkownika mogły być dołączane do jednostek programu i pobierane w czasie wykonywania.C# generalizes this capability such that user-defined types of declarative information can be attached to program entities and retrieved at run-time. Programy określają te dodatkowe informacje deklaracyjne przez definiowanie i używanie atrybutów.Programs specify this additional declarative information by defining and using attributes.

Poniższy przykład deklaruje HelpAttribute atrybut, który może być umieszczony w jednostkach programu, aby udostępnić linki do powiązanej dokumentacji.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; }
    }
}

Wszystkie klasy atrybutów pochodzą z System.Attribute klasy bazowej dostarczonej przez .NET Framework.All attribute classes derive from the System.Attribute base class provided by the .NET Framework. Atrybuty mogą być stosowane, dając ich nazwę, wraz z dowolnymi argumentami, wewnątrz nawiasów kwadratowych tuż przed skojarzoną deklaracją.Attributes can be applied by giving their name, along with any arguments, inside square brackets just before the associated declaration. Jeśli nazwa atrybutu zostanie zakończona Attribute, ta część nazwy może zostać pominięta, gdy występuje odwołanie do atrybutu.If an attribute's name ends in Attribute, that part of the name can be omitted when the attribute is referenced. Na przykład HelpAttribute atrybut może być używany w następujący sposób.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) {}
}

Ten HelpAttribute przykład dołącza Widget do klasyiHelpAttribute drugi do metodywklasie.DisplayThis example attaches a HelpAttribute to the Widget class and another HelpAttribute to the Display method in the class. Publiczne konstruktory klasy atrybutów kontrolują informacje, które muszą być dostarczone, gdy atrybut jest dołączony do jednostki programu.The public constructors of an attribute class control the information that must be provided when the attribute is attached to a program entity. Dodatkowe informacje można uzyskać, odwołując się do właściwości publicznego odczytu i zapisu klasy atrybutów (takich jak odwołanie do Topic właściwości wcześniej).Additional information can be provided by referencing public read-write properties of the attribute class (such as the reference to the Topic property previously).

Poniższy przykład pokazuje, jak informacje o atrybutach danej jednostki programu mogą być pobierane w czasie wykonywania przy użyciu odbicia.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"));
    }
}

Gdy określony atrybut jest żądany przez odbicie, Konstruktor klasy atrybutu jest wywoływany z informacjami podanymi w źródle programu i zwracane jest wystąpienie atrybutu wynikowego.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. Jeśli dodatkowe informacje zostały przekazane za pomocą właściwości, te właściwości są ustawiane na podane wartości przed zwróceniem wystąpienia atrybutu.If additional information was provided through properties, those properties are set to the given values before the attribute instance is returned.