소개Introduction

C#(“씨샵”이라고 발음합니다)은 간단하면서도 형식이 안전한 최신 개체 지향 프로그래밍 언어입니다.C# (pronounced "See Sharp") is a simple, modern, object-oriented, and type-safe programming language. C#은 C 언어의 루트를 포함 하 고 있으며 C, C++및 Java 프로그래머에 게 즉시 친숙 합니다.C# has its roots in the C family of languages and will be immediately familiar to C, C++, and Java programmers. C#는 ecma 국제에서 ecma-334 표준으로 표준화 되며 iso/Iec는 iso/iec 23270 표준으로 표준화 됩니다.C# is standardized by ECMA International as the ECMA-334 standard and by ISO/IEC as the ISO/IEC 23270 standard. .NET Framework에 C# 대 한 Microsoft의 컴파일러는 이러한 두 표준의 준수 구현입니다.Microsoft's C# compiler for the .NET Framework is a conforming implementation of both of these standards.

C#은 개체 지향 언어이지만 구성 요소 지향 프로그래밍도 지원합니다.C# is an object-oriented language, but C# further includes support for component-oriented programming. 현대의 소프트웨어 설계는 독립적이고 자체 설명적인 기능 패키지 형식을 갖는 소프트웨어 구성 요소에 점점 더 많이 의존하고 있습니다.Contemporary software design increasingly relies on software components in the form of self-contained and self-describing packages of functionality. 이러한 구성 요소의 핵심은 속성, 메서드 및 이벤트를 포함하는 프로그래밍 모델을 제공한다는 데 있습니다. 이러한 구성 요소는 구성 요소에 대한 선언적 정보를 제공하는 특성을 보유하며 자체 설명서를 통합하고 있습니다.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#는 이러한 개념을 C# 직접 지원 하 여 소프트웨어 구성 요소를 만들고 사용 하는 매우 자연 스러운 언어를 제공 하는 언어 구문을 제공 합니다.C# provides language constructs to directly support these concepts, making C# a very natural language in which to create and use software components.

몇 가지 C# 기능은 강력하고 안정적인 애플리케이션을 구축하는 데 도움을 줍니다. 가비지 수집은 사용 하지 않는 개체가 차지 하는 메모리를 자동으로 회수 합니다. 예외 처리 는 오류 검색 및 복구에 대 한 구조적이 고 확장 가능한 방법을 제공 합니다. 또한 형식이 안전한 언어 디자인에서는 초기화 되지 않은 변수를 읽을 수 없거나, 범위를 벗어나 배열을 인덱싱하고, 선택 되지 않은 형식 캐스팅을 수행할 수 없습니다.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#에는 통합 형식 시스템이 있습니다.C# has a unified type system. intdouble과 같은 기본 형식을 포함하는 모든 C# 형식은 단일 루트 object에서 상속됩니다.All C# types, including primitive types such as int and double, inherit from a single root object type. 따라서 일반적인 작업 집합을 공유하는 모든 형식과 모든 형식의 값을 일관된 방식으로 저장 및 전송하고 작업을 수행할 수 있습니다.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. 그뿐 아니라 C#은 사용자 정의 참조 형식 및 값 형식을 모두 지원하여 개체의 동적 할당과 더불어 간단한 구조의 인라인 스토리지도 구현합니다.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.

C# 프로그램 및 라이브러리가 호환 되는 방식으로 시간에 따라 진화 하 게 하려면 디자인의 버전 관리 C#에 많은 중점을 두어야 합니다.To ensure that C# programs and libraries can evolve over time in a compatible manner, much emphasis has been placed on versioning in C#'s design. 다양한 프로그래밍 언어가 이 문제를 등한시하여 결과적으로 해당 언어로 작성된 프로그램이 최신 버전의 종속 라이브러리가 도입될 때 필요한 것보다 더 자주 중단되게 되었습니다.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#버전 관리 고려 사항에 직접적으로 영향을 주는의 디자인 측면에 virtualoverride 별도의 및 한정자, 메서드 오버 로드 확인에 대 한 규칙 및 명시적 인터페이스 멤버 선언에 대 한 지원이 포함 됩니다.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.

이 장의 나머지 부분에서는 C# 언어의 주요 기능에 대해 설명 합니다.The rest of this chapter describes the essential features of the C# language. 이후 장에서는 세부 정보 지향적이 고 때로는 수학적 방식으로 규칙 및 예외를 설명 하지만이 장에서는 명확 하 게 이해 하 고 완전성을 위해 노력 하 고 있습니다.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. 초기 프로그램을 작성 하는 데 도움이 되는 언어에 대 한 소개와 이후 챕터의 읽기를 제공 하는 것이 목적입니다.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

“Hello, World” 프로그램은 프로그래밍 언어를 소개하는 데 일반적으로 사용됩니다.The "Hello, World" program is traditionally used to introduce a programming language. C#에서는 다음과 같습니다.Here it is in C#:

using System;

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

C# 소스 파일은 일반적으로 파일 확장명이 .cs입니다.C# source files typically have the file extension .cs. "Hello, 세계" 프로그램이 파일 hello.cs에 저장 되어 있는 경우 명령줄을 사용 하 여 Microsoft C# 컴파일러로 프로그램을 컴파일할 수 있습니다.Assuming 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

이라는 hello.exe실행 가능한 어셈블리가 생성 됩니다.which produces an executable assembly named hello.exe. 이 응용 프로그램이 실행 될 때 생성 되는 출력은 다음과 같습니다.The output produced by this application when it is run is

Hello, World

“Hello, World” 프로그램은 System 네임스페이스를 참조하는 using 지시문으로 시작합니다.The "Hello, World" program starts with a using directive that references the System namespace. 네임스페이스는 계층적으로 C# 프로그램 및 라이브러리를 구성하는 방법을 제공합니다.Namespaces provide a hierarchical means of organizing C# programs and libraries. 네임스페이스에는 형식 및 다른 네임스페이스가 포함됩니다. 예를 들어 System 네임스페이스에는 많은 형식(예: 프로그램에 참조되는 Console 클래스) 및 많은 다른 네임스페이스(예: IOCollections)가 포함되어 있습니다.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 지시문을 사용하여 해당 네임스페이스의 멤버인 형식을 정규화되지 않은 방식으로 사용할 수 있습니다.A using directive that references a given namespace enables unqualified use of the types that are members of that namespace. using 지시문 때문에, 프로그램은 Console.WriteLineSystem.Console.WriteLine의 약식으로 사용할 수 있습니다.Because of the using directive, the program can use Console.WriteLine as shorthand for System.Console.WriteLine.

“Hello, World” 프로그램에서 선언된 Hello 클래스에는 단일 멤버인 Main 메서드가 있습니다.The Hello class declared by the "Hello, World" program has a single member, the method named Main. 메서드는 static 한정자를 사용 하 여 선언 됩니다. MainThe Main method is declared with the static modifier. 인스턴스 메서드는 키워드 this를 사용하여 특정 바깥쪽 개체 인스턴스를 참조할 수 있지만 정적 메서드는 특정 개체에 대한 참조 없이 작동합니다.While instance methods can reference a particular enclosing object instance using the keyword this, static methods operate without reference to a particular object. 관례상 Main이라는 정적 메서드가 프로그램의 진입점으로 사용됩니다.By convention, a static method named Main serves as the entry point of a program.

프로그램의 출력은 System 네임스페이스에 있는 Console 클래스의 WriteLine 메서드에 의해 생성됩니다.The output of the program is produced by the WriteLine method of the Console class in the System namespace. 이 클래스는 기본적으로 Microsoft C# 컴파일러에서 자동으로 참조 하는 .NET Framework 클래스 라이브러리에서 제공 됩니다.This class is provided by the .NET Framework class libraries, which, by default, are automatically referenced by the Microsoft C# compiler. C# 자체에는 별도의 런타임 라이브러리가 없습니다.Note that C# itself does not have a separate runtime library. 대신 .NET Framework은의 C#런타임 라이브러리입니다.Instead, the .NET Framework is the runtime library of C#.

프로그램 구조Program structure

C#의 핵심적인 조직 개념은 프로그램, 네임스페이스, 형식, 멤버어셈블리입니다.The key organizational concepts in C# are programs, namespaces, types, members, and assemblies. C# 프로그램은 하나 이상의 소스 파일로 구성됩니다.C# programs consist of one or more source files. 프로그램은 멤버를 포함하고 네임스페이스로 구성될 수 있는 형식을 선언합니다.Programs declare types, which contain members and can be organized into namespaces. 클래스와 인터페이스는 형식의 예입니다.Classes and interfaces are examples of types. 필드, 메서드, 속성 및 이벤트는 멤버의 예입니다.Fields, methods, properties, and events are examples of members. C# 프로그램을 컴파일하면 실제로 어셈블리로 패키지됩니다.When C# programs are compiled, they are physically packaged into assemblies. 어셈블리는 일반적으로 응용 프로그램 또는 .dll 라이브러리를 구현 하는지에 따라 파일 확장명이 .exe 또는입니다.Assemblies typically have the file extension .exe or .dll, depending on whether they implement applications or libraries.

예제The 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;
            }
        }
    }
}

Stack 라는Acme.Collections네임 스페이스의 이라는 클래스를 선언 합니다.declares a class named Stack in a namespace called Acme.Collections. 이 클래스의 정규화된 이름은 Acme.Collections.Stack입니다.The fully qualified name of this class is Acme.Collections.Stack. 클래스에는 필드 top, 2개의 메서드 PushPop, 중첩된 클래스 Entry 등의 여러 멤버가 포함됩니다.The class contains several members: a field named top, two methods named Push and Pop, and a nested class named Entry. Entry 클래스는 필드 next 및 필드 data, 생성자의 세 멤버가 포함됩니다.The Entry class further contains three members: a field named next, a field named data, and a constructor. 예제의 소스 코드가 파일 acme.cs에 포함된다고 가정할 경우 다음 명령줄은Assuming that the source code of the example is stored in the file acme.cs, the command line

csc /t:library acme.cs

예제를 라이브러리(Main 진입점이 없는 코드)를 컴파일하고 acme.dll이라는 어셈블리를 생성합니다.compiles the example as a library (code without a Main entry point) and produces an assembly named acme.dll.

어셈블리에는 IL ( 중간 언어 ) 명령 형식의 실행 코드와 메타 데이터형식의 기호화 된 정보가 포함 되어 있습니다.Assemblies contain executable code in the form of Intermediate Language (IL) instructions, and symbolic information in the form of metadata. 실행되기 전에 어셈블리의 IL 코드는 .NET 공용 언어 런타임의 JIT(Just-In-Time) 컴파일러에 의해 자동으로 프로세서 특정 코드로 변환됩니다.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.

어셈블리는 코드와 메타데이터를 모두 포함하는 기능의 자체 설명 단위이므로 C#에 #include 지시문 및 헤더 파일이 필요하지 않습니다.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#. 특정 어셈블리에 포함된 공용 형식 및 멤버는 프로그램을 컴파일할 때 해당 어셈블리를 참조하는 것만으로 C# 프로그램에서 사용 가능해집니다.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. 예를 들어 이 프로그램에서는 acme.dll 어셈블리의 Acme.Collections.Stack 클래스를 사용합니다.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());
    }
}

test.cs프로그램이 파일 test.cs 에 저장 되어 있는 경우를 컴파일하면 acme.dll 컴파일러의 /r 옵션을 사용 하 여 어셈블리를 참조할 수 있습니다.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

이를 통해 실행 시 출력을 생성하는 test.exe라는 실행 가능한 어셈블리가 만들어집니다.This creates an executable assembly named test.exe, which, when run, produces the output:

100
10
1

C#은 프로그램의 소스 텍스트가 여러 소스 파일에 저장되도록 허용합니다.C# permits the source text of a program to be stored in several source files. 다중 파일 C# 프로그램이 컴파일되면 모든 소스 파일이 함께 처리되고 소스 파일은 서로 자유롭게 참조될 수 있습니다. 개념적으로는 마치 모든 소스 파일이 처리되기 전에 하나의 큰 파일로 연결되는 것처럼 보입니다.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. 극소수의 경우를 제외하고 선언 순서는 중요하지 않으므로 C#에서는 정방향 선언이 절대 필요하지 않습니다.Forward declarations are never needed in C# because, with very few exceptions, declaration order is insignificant. C#은 소스 파일을 하나의 공용 형식만 선언하도록 제한하거나 소스 파일 이름이 소스 파일에 선언된 형식과 일치하도록 요구하지 않습니다.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.

형식 및 변수Types and variables

C#에는 두 가지 종류의 형식, 즉 값 형식참조 형식이 있습니다.There are two kinds of types in C#: value types and reference types. 값 형식의 변수에는 해당 데이터가 직접 포함되지만 참조 형식의 변수에는 데이터(개체라고도 함)에 대한 참조가 저장됩니다.Variables of value types directly contain their data whereas variables of reference types store references to their data, the latter being known as objects. 참조 형식에서는 두 가지 변수가 같은 개체를 참조할 수 있으므로 한 변수에 대한 작업이 다른 변수에서 참조하는 개체에 영향을 미칠 수 있습니다.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. 값 형식에서는 변수에 데이터의 자체 사본이 들어 있으며 한 변수의 작업이 다른 변수에 영향을 미칠 수 없습니다(refout ref 및 out 매개 변수 제외).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#의 값 형식은 단순 형식, 열거형 형식, 구조체 형식nullable 형식으로 세분화 되며, C#의 참조 형식은 클래스 형식, 인터페이스 형식, 배열로 추가로 나뉩니다. 형식대리자 형식.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.

다음 표에서는의 형식 시스템에 C#대 한 개요를 제공 합니다.The following table provides an overview of C#'s type system.

범주Category 설명Description
값 형식Value types 단순 형식Simple types 부호 있는 정수: sbyte, short, int,longSigned integral: sbyte, short, int, long
부호 없는 정수: byte, ushort, uint,ulongUnsigned integral: byte, ushort, uint, ulong
유니코드 문자: charUnicode characters: char
IEEE 부동 소수점: float, doubleIEEE floating point: float, double
High-Precision 10진수:decimalHigh-precision decimal: decimal
부울: boolBoolean: bool
열거형Enum types enum E {...} 양식의 사용자 정의 형식User-defined types of the form enum E {...}
구조체 형식Struct types struct S {...} 양식의 사용자 정의 형식User-defined types of the form struct S {...}
Nullable 형식Nullable types null 값을 갖는 다른 모든 값 형식의 확장Extensions of all other value types with a null value
참조 형식Reference types 클래스 형식Class types 다른 모든 형식의 기본 클래스: objectUltimate base class of all other types: object
유니코드 문자열: stringUnicode strings: string
class C {...} 양식의 사용자 정의 형식User-defined types of the form class C {...}
인터페이스 형식Interface types interface I {...} 양식의 사용자 정의 형식User-defined types of the form interface I {...}
배열 형식Array types 단일 차원 및 다차원(예: int[]int[,])Single- and multi-dimensional, for example, int[] and int[,]
대리자 형식Delegate types 사용자 정의 형식 (예:)delegate int D(...)User-defined types of the form e.g. delegate int D(...)

8가지 정수 형식은 부호 있는 형식 또는 부호 없는 형식으로 8비트, 16비트, 32비트 및 64비트 값에 대한 지원을 제공합니다.The eight integral types provide support for 8-bit, 16-bit, 32-bit, and 64-bit values in signed or unsigned form.

두 부동 소수점 형식 floatdouble는 32 비트 단 정밀도 및 64 비트 배정밀도 IEEE 754 형식을 사용 하 여 표현 됩니다.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 형식은 재무 및 통화 계산에 적합한 128비트 데이터 형식입니다.The decimal type is a 128-bit data type suitable for financial and monetary calculations.

C#의 bool 형식은 부울 값을 나타내는 데 사용 되며, 값 true 은 또는 false입니다.C#'s bool type is used to represent boolean values—values that are either true or false.

C#의 문자 및 문자열 처리에서는 유니코드 인코딩이 사용됩니다.Character and string processing in C# uses Unicode encoding. char 형식은 UTF-16 코드 단위를 나타내고, string 형식은 UTF-16 코드 단위 시퀀스를 나타냅니다.The char type represents a UTF-16 code unit, and the string type represents a sequence of UTF-16 code units.

다음 표에서는 숫자 C#형식을 요약 합니다.The following table summarizes C#'s numeric types.

범주Category 비트씩Bits 형식Type 범위/전체 자릿수Range/Precision
부호 있는 정수Signed integral 88 sbyte -128...127-128...127
1616 short -32,768...32,767-32,768...32,767
3232 int -2,147,483,648...2,147,483,647-2,147,483,648...2,147,483,647
6464 long -9,223,372,036,854,775,808...9,223,372,036,854,775,807-9,223,372,036,854,775,808...9,223,372,036,854,775,807
부호 없는 정수Unsigned 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
부동 소수점Floating point 3232 float 1.5 × 10 ^ − 45 ~ 3.4 × 10 ^ 38, 7 자리 전체 자릿수1.5 × 10^−45 to 3.4 × 10^38, 7-digit precision
6464 double 5.0 × 10 ^ − 324 ~ 1.7 × 10 ^ 308, 15 자리 전체 자릿수5.0 × 10^−324 to 1.7 × 10^308, 15-digit precision
DecimalDecimal 128128 decimal 1.0 × 10 ^ − 28 ~ 7.9 × 10 ^ 28, 28 자리 전체 자릿수1.0 × 10^−28 to 7.9 × 10^28, 28-digit precision

C# 프로그램에서는 형식 선언을 사용하여 새 형식을 만듭니다.C# programs use type declarations to create new types. 형식 선언은 새 형식의 이름과 멤버를 지정합니다.A type declaration specifies the name and the members of the new type. 의 형식 C#범주 중 5 개는 클래스 형식, 구조체 형식, 인터페이스 형식, 열거형 형식 및 대리자 형식과 같이 사용자가 정의할 수 있습니다.Five of C#'s categories of types are user-definable: class types, struct types, interface types, enum types, and delegate types.

클래스 형식은 데이터 멤버 (필드) 및 함수 멤버 (메서드, 속성 및 기타)를 포함 하는 데이터 구조를 정의 합니다.A class type defines a data structure that contains data members (fields) and function members (methods, properties, and others). 클래스 형식은 단일 상속 및 다형성과 파생된 클래스가 기본 클래스를 확장하고 특수화할 수 있는 메커니즘을 지원합니다.Class types support single inheritance and polymorphism, mechanisms whereby derived classes can extend and specialize base classes.

구조체 형식은 데이터 멤버 및 함수 멤버를 포함 하는 구조체를 나타내므로의 클래스 형식과 비슷합니다.A struct type is similar to a class type in that it represents a structure with data members and function members. 그러나 클래스와 달리 구조체는 값 형식이 며 힙 할당이 필요 하지 않습니다.However, unlike classes, structs are value types and do not require heap allocation. 구조체 형식은 사용자 지정 상속을 지원하지 않으며 모든 구조체 형식은 object 형식에서 암시적으로 상속됩니다.Struct types do not support user-specified inheritance, and all struct types implicitly inherit from type object.

인터페이스 형식은 계약을 public 함수 멤버의 명명 된 집합으로 정의 합니다.An interface type defines a contract as a named set of public function members. 인터페이스를 구현 하는 클래스 또는 구조체는 인터페이스의 함수 멤버에 대 한 구현을 제공 해야 합니다.A class or struct that implements an interface must provide implementations of the interface's function members. 인터페이스는 여러 기본 인터페이스에서 상속할 수 있으며, 클래스 또는 구조체는 여러 인터페이스를 구현할 수 있습니다.An interface may inherit from multiple base interfaces, and a class or struct may implement multiple interfaces.

대리자 형식은 특정 매개 변수 목록 및 반환 형식이 있는 메서드에 대 한 참조를 나타냅니다.A delegate type represents references to methods with a particular parameter list and return type. 대리자는 메서드를 변수에 할당되고 매개 변수로 전달될 수 있는 엔터티로 취급할 수 있도록 합니다.Delegates make it possible to treat methods as entities that can be assigned to variables and passed as parameters. 또한 대리자는 다른 언어에 나오는 함수 포인터의 개념과 비슷하지만 함수 포인터와 달리 대리자는 개체 지향적이며 형식 안전 방식입니다.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.

클래스, 구조체, 인터페이스 및 대리자 형식은 모두 제네릭을 지원 하므로 다른 형식으로 매개 변수화 할 수 있습니다.Class, struct, interface and delegate types all support generics, whereby they can be parameterized with other types.

열거형 형식은 명명 된 상수가 있는 고유 형식입니다.An enum type is a distinct type with named constants. 모든 열거형 형식에는 8 개의 정수 계열 형식 중 하나 여야 하는 기본 형식이 있습니다.Every enum type has an underlying type, which must be one of the eight integral types. 열거형 형식의 값 집합은 내부 형식의 값 집합과 동일 합니다.The set of values of an enum type is the same as the set of values of the underlying type.

C#은 형식의 단일 차원 및 다차원 배열을 지원합니다.C# supports single- and multi-dimensional arrays of any type. 위에 나열된 형식과 달리, 배열 형식은 사용하기 전에 먼저 선언할 필요가 없습니다.Unlike the types listed above, array types do not have to be declared before they can be used. 대신, 배열 형식은 형식 이름을 대괄호로 묶어 생성합니다.Instead, array types are constructed by following a type name with square brackets. int[] 예를 들어은의 1 차원 int int배열이 int[,] 고,는의 2 차원 배열이 고,은의 int1 int[][] 차원 배열에 해당 하는 1 차원 배열입니다.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.

또한 Nullable 형식을 사용 하려면 먼저 선언 하지 않아도 됩니다.Nullable types also do not have to be declared before they can be used. Null을 허용 하지 않는 각 값 T 형식에 대해 추가 값 nullT?보유할 수 있는 해당 nullable 형식이 있습니다.For each non-nullable value type T there is a corresponding nullable type T?, which can hold an additional value null. 예를 들어 int? 는 32 비트 정수 또는 값 null을 보유할 수 있는 형식입니다.For instance, int? is a type that can hold any 32 bit integer or the value null.

C#의 형식 시스템은 통합 되어 모든 형식의 값을 개체로 처리할 수 있습니다.C#'s type system is unified such that a value of any type can be treated as an object. C#의 모든 형식은 object 클래스 형식에서 직접 또는 간접적으로 파생되고 object는 모든 형식의 기본 클래스입니다.Every type in C# directly or indirectly derives from the object class type, and object is the ultimate base class of all types. 참조 형식의 값은 object로 인식함으로써 간단히 개체로 처리됩니다.Values of reference types are treated as objects simply by viewing the values as type object. 값 형식의 값은 boxingunboxing 작업을 수행 하 여 개체로 처리 됩니다.Values of value types are treated as objects by performing boxing and unboxing operations. 다음 예제에서 int 값은 object로 변환되었다가 다시 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
    }
}

값 형식의 값이 형식 object으로 변환 되 면 "box" 라고도 하는 개체 인스턴스가 값을 보유 하기 위해 할당 되 고 값이 해당 상자에 복사 됩니다.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. 반대로 object 참조가 값 형식으로 캐스팅 되는 경우 참조 되는 개체가 올바른 값 형식의 상자 인지 확인 하 고, 검사에 성공 하면 상자의 값이 복사 됩니다.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#의 통합 형식 시스템은 값 형식이 "요청 시" 개체가 될 수 있음을 의미 합니다.C#'s unified type system effectively means that value types can become objects "on demand." 통합 때문에 object 형식을 사용하는 범용 라이브러리는 참조 형식 및 값 형식 둘 다에 사용될 수 있습니다.Because of the unification, general-purpose libraries that use type object can be used with both reference types and value types.

C#에는 필드, 배열 요소, 지역 변수 및 매개 변수를 포함하는 여러 종류의 변수가 있습니다.There are several kinds of variables in C#, including fields, array elements, local variables, and parameters. 변수는 저장소 위치를 나타내며 모든 변수에는 다음 표와 같이 변수에 저장할 수 있는 값을 결정 하는 형식이 있습니다.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.

변수의 형식입니다.Type of Variable 가능한 내용Possible Contents
Null을 허용하지 않는 값 형식Non-nullable value type 정확한 해당 형식의 값A value of that exact type
Null 허용 값 형식Nullable value type Null 값 이거나 정확한 형식의 값입니다.A null value or a value of that exact type
object Null 참조, 참조 형식의 개체에 대 한 참조 또는 모든 값 형식의 boxed 값에 대 한 참조A null reference, a reference to an object of any reference type, or a reference to a boxed value of any value type
클래스 형식Class type Null 참조, 해당 클래스 형식의 인스턴스에 대 한 참조 또는 해당 클래스 형식에서 파생 된 클래스의 인스턴스에 대 한 참조입니다.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
인터페이스 유형Interface type Null 참조, 해당 인터페이스 형식을 구현 하는 클래스 형식의 인스턴스에 대 한 참조 또는 해당 인터페이스 형식을 구현 하는 값 형식의 boxed 값에 대 한 참조입니다.A null reference, a reference to an instance of a class type that implements that interface type, or a reference to a boxed value of a value type that implements that interface type
배열 형식Array type Null 참조, 해당 배열 형식의 인스턴스에 대 한 참조 또는 호환 되는 배열 형식의 인스턴스에 대 한 참조입니다.A null reference, a reference to an instance of that array type, or a reference to an instance of a compatible array type
대리자 형식Delegate type Null 참조 또는 해당 대리자 형식의 인스턴스에 대 한 참조입니다.A null reference or a reference to an instance of that delegate type

표현식Expressions

피연산자연산자로 생성됩니다.Expressions are constructed from operands and operators. 식의 연산자는 피연산자에 적용할 연산을 나타냅니다.The operators of an expression indicate which operations to apply to the operands. 연산자의 예로 +, -, *, /new가 있습니다.Examples of operators include +, -, *, /, and new. 피연산자의 예로는 리터럴, 필드, 지역 변수 및 식이 있습니다.Examples of operands include literals, fields, local variables, and expressions.

식에 여러 연산자가 포함되어 있으면 연산자의 우선 순위에 따라 개별 연산자가 계산되는 순서가 제어됩니다.When an expression contains multiple operators, the precedence of the operators controls the order in which the individual operators are evaluated. 예를 들어 * 연산자는 + 연산자보다 우선 순위가 더 높기 때문에 식 x + y * zx + (y * z)로 계산됩니다.For example, the expression x + y * z is evaluated as x + (y * z) because the * operator has higher precedence than the + operator.

대부분의 연산자는 오버로드할 수 있습니다.Most operators can be overloaded. 연산자 오버로드는 피연산자 중 하나 또는 둘 다가 사용자 정의 클래스 또는 구조체 형식인 연산에 대해 사용자 정의 연산자 구현을 지정할 수 있도록 허용합니다.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.

다음 표에서는 연산자 C#를 요약 하 여 가장 높은 우선 순위 순으로 연산자 범주를 나열 합니다.The following table summarizes C#'s operators, listing the operator categories in order of precedence from highest to lowest. 동일한 범주의 연산자는 우선 순위가 같습니다.Operators in the same category have equal precedence.

범주Category Expression 설명Description
Primary x.m 멤버 액세스Member access
x(...) 메서드 및 대리자 호출Method and delegate invocation
x[...] 배열 및 인덱서 액세스Array and indexer access
x++ 후위 증가Post-increment
x-- 후위 감소Post-decrement
new T(...) 개체 및 대리자 생성Object and delegate creation
new T(...){...} 이니셜라이저를 사용한 개체 생성Object creation with initializer
new {...} 익명 개체 이니셜라이저Anonymous object initializer
new T[...] 배열 생성Array creation
typeof(T) T에 대한 System.Type 개체 가져오기Obtain System.Type object for T
checked(x) checked 컨텍스트에서 식 계산Evaluate expression in checked context
unchecked(x) unchecked 컨텍스트에서 식 계산Evaluate expression in unchecked context
default(T) T 형식의 기본값 가져오기Obtain default value of type T
delegate {...} 익명 함수(무명 메서드)Anonymous function (anonymous method)
단항Unary +x IDIdentity
-x 부정Negation
!x 논리 부정Logical negation
~x 비트 부정 연산Bitwise negation
++x 전위 증가Pre-increment
--x 전위 감소Pre-decrement
(T)x xT 형식으로 명시적 변환Explicitly convert x to type T
await x 비동기적으로 x 완료 대기Asynchronously wait for x to complete
곱하기Multiplicative x * y 곱하기Multiplication
x / y 나눗셈 기호Division
x % y 나머지Remainder
더하기Additive x + y 더하기, 문자열 연결, 대리자 결합Addition, string concatenation, delegate combination
x - y 빼기, 대리자 제거Subtraction, delegate removal
ShiftShift x << y 왼쪽 시프트Shift left
x >> y 오른쪽 시프트Shift right
관계형 및 형식 테스트Relational and type testing x < y 보다 작음Less than
x > y 보다 큼Greater than
x <= y 다음보다 적거나 같음Less than or equal
x >= y 크거나 같음Greater than or equal
x is T xT이면 true 반환, 그렇지 않으면 false 반환Return true if x is a T, false otherwise
x as T T로 형식이 지정된 x 반환, xT가 아닌 경우 null 반환Return x typed as T, or null if x is not a T
같음Equality x == y 같음Equal
x != y 다음과 같지 않음Not equal
논리적 ANDLogical AND x & y 정수 비트 AND, 부울 논리곱 ANDInteger bitwise AND, boolean logical AND
논리 XORLogical XOR x ^ y 정수 비트 XOR, 부울 논리곱 XORInteger bitwise XOR, boolean logical XOR
논리적 ORLogical OR x | y 정수 비트 OR, 부울 논리곱 ORInteger bitwise OR, boolean logical OR
조건부 ANDConditional AND x && y y 인 경우 x 에만 평가 됩니다.trueEvaluates y only if x is true
조건부 ORConditional OR x || y y 인 경우 x 에만 평가 됩니다.falseEvaluates y only if x is false
Null 결합Null coalescing x ?? y 가 이면이 고 null ,x 그렇지 않으면로 평가 됩니다. y xEvaluates to y if x is null, to x otherwise
조건Conditional x ? y : z xtrue이면 y, xfalse이면 z로 평가Evaluates y if x is true, z if x is false
대입 또는 익명 함수Assignment or anonymous function x = y 할당Assignment
x op= y 복합 할당; 지원 되는 *=연산자 -= /= %= += <<= >>= &= ^=|=Compound assignment; supported operators are *= /= %= += -= <<= >>= &= ^= |=
(T x) => y 익명 함수(람다 식)Anonymous function (lambda expression)

Statements

프로그램의 동작은 을 사용하여 표현됩니다.The actions of a program are expressed using statements. C#은 여러 다른 종류의 문을 지원하며 이중 많은 문이 포함 문에 대해 정의됩니다.C# supports several different kinds of statements, a number of which are defined in terms of embedded statements.

블록은 단일 문이 허용되는 컨텍스트에서 여러 문을 쓸 수 있도록 허용합니다.A block permits multiple statements to be written in contexts where a single statement is allowed. 블록은 구분 기호 {} 사이에 쓴 문 목록으로 구성됩니다.A block consists of a list of statements written between the delimiters { and }.

선언 문은 지역 변수 및 상수를 선언하는 데 사용됩니다.Declaration statements are used to declare local variables and constants.

식 문은 식을 평가하는 데 사용됩니다.Expression statements are used to evaluate expressions. 문으로 사용할 수 있는 식에는 메서드 호출, new 연산자를 사용 하는 개체 할당, = 및 복합 할당 연산자를 사용 하는 할당,를 사용 하 ++는증가및감소작업등이있습니다. and-- 연산자 및 wait 식.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.

선택 문은 일부 식 값에 따라 실행할 수 있는 다양한 문 중에서 하나를 선택하는 데 사용됩니다.Selection statements are used to select one of a number of possible statements for execution based on the value of some expression. 이 그룹에는 ifswitch 문이 포함됩니다.In this group are the if and switch statements.

반복 문은 포함 문을 반복 해 서 실행 하는 데 사용 됩니다.Iteration statements are used to repeatedly execute an embedded statement. 이 그룹에는 while, do, forforeach 문이 포함됩니다.In this group are the while, do, for, and foreach statements.

점프 문은 제어를 전달하는 데 사용됩니다.Jump statements are used to transfer control. 이 그룹에는 break, continue, goto, throw, returnyield 문이 포함됩니다.In this group are the break, continue, goto, throw, return, and yield statements.

try... catch 문은 블록 실행 중에 발생하는 예외를 catch하는 데 사용되고 try... finally 문은 예외 발생 여부에 관계 없이 항상 실행되는 종료 코드를 지정하는 데 사용됩니다.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.

checkedunchecked 문은 정수 계열 형식 산술 연산 및 변환에 대 한 오버플로 검사 컨텍스트를 제어 하는 데 사용 됩니다.The checked and unchecked statements are used to control the overflow checking context for integral-type arithmetic operations and conversions.

lock 문은 지정된 개체에 대한 상호 배타적 잠금을 획득하고, 문을 실행한 후 잠금을 해제하는 데 사용됩니다.The lock statement is used to obtain the mutual-exclusion lock for a given object, execute a statement, and then release the lock.

using 문은 리소스를 획득하고, 문을 실행한 후 해당 리소스를 삭제하는 데 사용됩니다.The using statement is used to obtain a resource, execute a statement, and then dispose of that resource.

다음은 각 종류의 문 예입니다.Below are examples of each kind of statement

지역 변수 선언Local variable declarations

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

지역 상수 선언Local constant declaration

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

식 문Expression statement

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

if statementif statement

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

switch statementswitch 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;
    }
}

while statementwhile statement

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

do statementdo statement

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

for statementfor statement

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

foreach statementforeach statement

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

break statementbreak statement

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

continue statementcontinue statement

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

goto statementgoto statement

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

return statementreturn statement

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

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

yield statementyield 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);
    }
}

throwtrythrow 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!");
    }
}

checkeduncheckedchecked and unchecked statements

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

lock statementlock statement

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

using statementusing statement

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

클래스 및 개체Classes and objects

클래스는 C#의 가장 기본적인 형식입니다.Classes are the most fundamental of C#'s types. 클래스는 상태(필드)와 작업(메서드 및 기타 함수 멤버)을 하나의 단위로 결합하는 데이터 구조입니다.A class is a data structure that combines state (fields) and actions (methods and other function members) in a single unit. 클래스는 해당 클래스의 동적으로 생성된 인스턴스(개체라고도 함)에 대한 정의를 제공합니다.A class provides a definition for dynamically created instances of the class, also known as objects. 클래스는 상속다형성파생된 클래스기본 클래스를 확장하고 특수화할 수 있는 메커니즘을 지원합니다.Classes support inheritance and polymorphism, mechanisms whereby derived classes can extend and specialize base classes.

새 클래스는 클래스 선언을 사용하여 만들어집니다.New classes are created using class declarations. 클래스 선언은 클래스의 특성 및 한정자, 클래스의 이름, 기본 클래스(제공된 경우), 클래스로 구현되는 인터페이스를 지정하는 헤더로 시작합니다.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. 헤더 다음에는 구분 기호 {} 간에 작성되는 멤버 선언 목록으로 구성되는 클래스 본문이 나옵니다.The header is followed by the class body, which consists of a list of member declarations written between the delimiters { and }.

다음은 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;
    }
}

클래스의 인스턴스는 새 인스턴스에 대한 메모리를 할당하고, 인스턴스를 초기화하는 생성자를 호출하고, 인스턴스에 대한 참조를 반환하는 new 연산자를 사용하여 만들어집니다.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. 다음 문은 두 개의 Point 개체를 만들고 해당 개체에 대 한 참조를 두 변수에 저장 합니다.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);

개체가 차지 하는 메모리는 개체가 더 이상 사용 되지 않을 때 자동으로 회수 됩니다.The memory occupied by an object is automatically reclaimed when the object is no longer in use. C#에서 개체를 명시적으로 할당 취소할 필요도 없으며 가능하지도 않습니다.It is neither necessary nor possible to explicitly deallocate objects in C#.

멤버Members

클래스의 멤버는 정적 멤버 또는 인스턴스 멤버입니다.The members of a class are either static members or instance members. 정적 멤버는 클래스에 속하며 인스턴스 멤버는 개체(클래스의 인스턴스)에 속합니다.Static members belong to classes, and instance members belong to objects (instances of classes).

다음 표에서는 클래스가 포함할 수 있는 멤버의 종류에 대 한 개요를 제공 합니다.The following table provides an overview of the kinds of members a class can contain.

멤버Member 설명Description
상수Constants 클래스와 연결된 상수 값Constant values associated with the class
필드Fields 클래스의 변수Variables of the class
메서드Methods 클래스가 수행할 수 있는 계산 및 작업Computations and actions that can be performed by the class
속성Properties 클래스의 명명된 속성에 대한 읽기 및 쓰기와 관련된 작업Actions associated with reading and writing named properties of the class
인덱서Indexers 클래스 인스턴스를 배열처럼 인덱싱하는 것과 관련된 작업Actions associated with indexing instances of the class like an array
이벤트Events 클래스에 의해 생성될 수 있는 알림Notifications that can be generated by the class
연산자Operators 클래스가 지원하는 변환 및 식 연산자Conversions and expression operators supported by the class
생성자Constructors 클래스의 인스턴스 또는 클래스 자체를 초기화하는 데 필요한 작업Actions required to initialize instances of the class or the class itself
소멸자Destructors 클래스의 인스턴스가 영구적으로 삭제되기 전에 수행 작업Actions to perform before instances of the class are permanently discarded
유형Types 클래스에 의해 선언된 중첩 형식Nested types declared by the class

액세스 가능성Accessibility

클래스의 각 멤버에는 멤버에 액세스할 수 있는 프로그램 텍스트의 영역을 제어하는 액세스 가능성이 연결되어 있습니다.Each member of a class has an associated accessibility, which controls the regions of program text that are able to access the member. 액세스 가능성은 5가지 형태로 제공됩니다.There are five possible forms of accessibility. 각각은 다음 표에 요약되어 있습니다.These are summarized in the following table.

액세스 가능성Accessibility 임을Meaning
public 액세스가 제한되지 않음Access not limited
protected 이 클래스 또는 이 클래스에서 파생된 클래스로만 액세스가 제한됨Access limited to this class or classes derived from this class
internal 이 프로그램으로만 액세스가 제한됨Access limited to this program
protected internal 이 프로그램 또는 이 클래스에서 파생된 클래스로만 액세스가 제한됨Access limited to this program or classes derived from this class
private 이 클래스로만 액세스가 제한됨Access limited to this class

형식 매개 변수Type parameters

클래스 정의는 클래스 이름 다음에 대괄호로 묶은 형식 매개 변수 이름 목록을 지정하여 형식 매개 변수 집합을 지정할 수 있습니다.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. 형식 매개 변수는 클래스 선언 본문에서 클래스의 멤버를 정의 하는 데 사용할 수 있습니다.The type parameters can the be used in the body of the class declarations to define the members of the class. 다음 예제에서 Pair의 형식 매개 변수는 TFirstTSecond입니다.In the following example, the type parameters of Pair are TFirst and TSecond:

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

형식 매개 변수를 사용 하도록 선언 된 클래스 형식을 제네릭 클래스 형식 이라고 합니다.A class type that is declared to take type parameters is called a generic class type. 구조체, 인터페이스 및 대리자 형식도 제네릭일 수 있습니다.Struct, interface and delegate types can also be generic.

제네릭 클래스를 사용하는 경우 각 형식 매개 변수에 대해 다음과 같은 형식 인수가 제공되어야 합니다.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

위와 같이 Pair<int,string> 형식 인수를 제공 하는 제네릭 형식을 생성 된 형식 이라고 합니다.A generic type with type arguments provided, like Pair<int,string> above, is called a constructed type.

기본 클래스Base classes

클래스 선언은 클래스 이름 및 형식 매개 변수 뒤에 콜론과 기본 클래스의 이름을 사용하여 기본 클래스를 지정할 수 있습니다.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. 기본 클래스 지정을 생략하면 object 형식에서 파생되는 클래스와 같습니다.Omitting a base class specification is the same as deriving from type object. 다음 예제에서 Point3D의 기본 클래스는 Point이고 Point의 기본 클래스는 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;
    }
}

클래스는 기본 클래스의 멤버를 상속합니다.A class inherits the members of its base class. 상속은 인스턴스 및 정적 생성자와 기본 클래스의 소멸자를 제외 하 고, 클래스에 기본 클래스의 모든 멤버를 암시적으로 포함 하는 것을 의미 합니다.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. 파생된 클래스를 상속하는 대상에 새 멤버를 추가할 수 있지만 상속된 멤버의 정의를 제거할 수 없습니다.A derived class can add new members to those it inherits, but it cannot remove the definition of an inherited member. 앞의 예제에서 Point3DPoint에서 xy 필드를 상속하고 모든 Point3D 인스턴스는 세 개의 필드, 즉 x, yz를 포함합니다.In the previous example, Point3D inherits the x and y fields from Point, and every Point3D instance contains three fields, x, y, and z.

클래스 형식에서 해당 기본 클래스 형식 간에 암시적 변환이 존재합니다.An implicit conversion exists from a class type to any of its base class types. 따라서 클래스 형식의 변수는 해당 클래스의 인스턴스 또는 파생된 모든 클래스의 인스턴스를 참조할 수 있습니다.Therefore, a variable of a class type can reference an instance of that class or an instance of any derived class. 예를 들어 이전 클래스 선언에서 형식 Point의 변수는 Point 또는 Point3D를 참조할 수 있습니다.For example, given the previous class declarations, a variable of type Point can reference either a Point or a Point3D:

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

필드Fields

필드는 클래스 또는 클래스의 인스턴스와 연결 된 변수입니다.A field is a variable that is associated with a class or with an instance of a class.

static 한정자를 사용 하 여 선언 된 필드는 정적 필드를 정의 합니다.A field declared with the static modifier defines a static field. 정적 필드는 정확히 하나의 스토리지 위치를 식별합니다.A static field identifies exactly one storage location. 생성된 클래스 인스턴스 수에 관계없이 정적 필드의 복사본은 하나뿐입니다.No matter how many instances of a class are created, there is only ever one copy of a static field.

한정자를 static 사용 하지 않고 선언 된 필드는 인스턴스 필드를 정의 합니다.A field declared without the static modifier defines an instance field. 클래스의 모든 인스턴스는 해당 클래스의 모든 인스턴스 필드의 별도 복사본을 포함합니다.Every instance of a class contains a separate copy of all the instance fields of that class.

다음 예제에서 Color 클래스의 각 인스턴스는 r, gb 인스턴스 필드의 별도 복사본을 갖지만 Black, White, Red, GreenBlue 정적 필드의 복사본은 하나뿐입니다.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;
    }
}

앞의 예제와 같이 읽기 전용 필드readonly 한정자를 사용하여 선언될 수 있습니다.As shown in the previous example, read-only fields may be declared with a readonly modifier. 필드에 대 readonly 한 할당은 필드의 선언이 나 같은 클래스의 생성자 에서만 발생할 수 있습니다.Assignment to a readonly field can only occur as part of the field's declaration or in a constructor in the same class.

메서드Methods

메서드는 개체 또는 클래스에서 수행할 수 있는 계산이나 작업을 구현하는 멤버입니다.A method is a member that implements a computation or action that can be performed by an object or class. 정적 메서드는 클래스를 통해 액세스됩니다.Static methods are accessed through the class. 인스턴스 메서드는 클래스의 인스턴스를 통해 액세스됩니다.Instance methods are accessed through instances of the class.

메서드에는 메서드에 전달 되는 값 또는 변수 참조를 나타내는 매개 변수의목록 (비어 있을 수 있음) 및 메서드에서 계산 되 고 반환 되는 값의 형식을 지정 하는 반환 형식이있습니다.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. 값을 반환 하지 않는 메서드의 void 반환 형식은입니다.A method's return type is void if it does not return a value.

형식과 마찬가지로 메서드에는 메서드가 호출될 때 형식 인수가 지정되어야 하는 형식 매개 변수 집합도 있을 수 있습니다.Like types, methods may also have a set of type parameters, for which type arguments must be specified when the method is called. 형식과 달리 형식 인수는 종종 메서드 호출의 인수에서 유추될 수 있으므로 명시적으로 지정할 필요가 없습니다.Unlike types, the type arguments can often be inferred from the arguments of a method call and need not be explicitly given.

메서드의 시그니처는 메서드가 선언되는 클래스에서 고유해야 합니다.The signature of a method must be unique in the class in which the method is declared. 메서드 시그니처는 메서드의 이름, 형식 매개 변수의 수, 해당 매개 변수의 수, 한정자 및 형식으로 구성됩니다.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. 메서드 시그니처는 반환 형식을 포함하지 않습니다.The signature of a method does not include the return type.

매개 변수Parameters

매개 변수는 메서드에 값 또는 변수 참조를 전달하는 데 사용됩니다.Parameters are used to pass values or variable references to methods. 메서드의 매개 변수는 메서드가 호출될 때 지정된 인수에서 실제 값을 가져옵니다.The parameters of a method get their actual values from the arguments that are specified when the method is invoked. 매개 변수에는 값 매개 변수, 참조 매개 변수, 출력 매개 변수 및 매개 변수 배열의 네 가지 종류가 있습니다.There are four kinds of parameters: value parameters, reference parameters, output parameters, and parameter arrays.

값 매개 변수는 입력 매개 변수 전달에 사용됩니다.A value parameter is used for input parameter passing. 값 매개 변수는 매개 변수에 전달된 인수에서 초기 값을 가져오는 지역 변수에 해당합니다.A value parameter corresponds to a local variable that gets its initial value from the argument that was passed for the parameter. 값 매개 변수를 수정해도 매개 변수에 전달된 인수에는 영향을 주지 않습니다.Modifications to a value parameter do not affect the argument that was passed for the parameter.

해당 인수를 생략할 수 있도록 기본값을 지정하면 값 매개 변수는 선택적일 수 있습니다.Value parameters can be optional, by specifying a default value so that corresponding arguments can be omitted.

참조 매개 변수는 입력 및 출력 매개 변수 전달 둘 다에 사용됩니다.A reference parameter is used for both input and output parameter passing. 참조 매개 변수에 전달되는 인수는 변수여야 하며, 메서드를 실행하는 동안 참조 매개 변수는 인수 변수와 동일한 스토리지 위치를 나타냅니다.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. 참조 매개 변수는 ref 한정자를 사용하여 선언됩니다.A reference parameter is declared with the ref modifier. 다음 예제에서는 ref 매개 변수를 사용하는 방법을 보여 줍니다.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"
    }
}

출력 매개 변수는 출력 매개 변수 전달에 사용됩니다.An output parameter is used for output parameter passing. 출력 매개 변수는 호출자가 제공한 인수의 초기 값이 중요하지 않다는 점을 제외하고 참조 매개 변수와 비슷합니다.An output parameter is similar to a reference parameter except that the initial value of the caller-provided argument is unimportant. 출력 매개 변수는 out 한정자를 사용하여 선언됩니다.An output parameter is declared with the out modifier. 다음 예제에서는 out 매개 변수를 사용하는 방법을 보여 줍니다.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"
    }
}

매개 변수 배열은 다양한 개수의 인수가 메서드에 전달되도록 허용합니다.A parameter array permits a variable number of arguments to be passed to a method. 매개 변수 배열은 params 한정자를 사용하여 선언됩니다.A parameter array is declared with the params modifier. 메서드의 마지막 매개 변수만 매개 변수 배열일 수 있으며 매개 변수 배열의 형식은 1차원 배열 형식이어야 합니다.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. 클래스의 WriteLine Write 및메서드는매개변수배열사용의좋은예입니다System.Console .The Write and WriteLine methods of the System.Console class are good examples of parameter array usage. 이러한 메서드는 다음과 같이 선언됩니다.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) {...}
    ...
}

매개 변수 배열을 사용하는 메서드 내에서 매개 변수 배열은 배열 형식의 일반 매개 변수와 정확히 동일하게 동작합니다.Within a method that uses a parameter array, the parameter array behaves exactly like a regular parameter of an array type. 그러나 매개 변수 배열을 사용한 메서드 호출에서 매개 변수 배열 형식의 단일 인수 또는 매개 변수 배열에 있는 임의 개수의 요소 형식 인수를 전달할 수 있습니다.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. 후자의 경우 지정된 인수를 사용하여 배열 인스턴스가 자동으로 만들어지고 초기화됩니다.In the latter case, an array instance is automatically created and initialized with the given arguments. 다음 예제는This example

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

다음을 작성하는 것과 같습니다.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);

메서드 본문 및 지역 변수Method body and local variables

메서드 본문은 메서드가 호출 될 때 실행할 문을 지정 합니다.A method's body specifies the statements to execute when the method is invoked.

메서드 본문은 메서드 호출과 관련된 변수를 선언할 수 있습니다.A method body can declare variables that are specific to the invocation of the method. 이러한 변수를 지역 변수라고 합니다.Such variables are called local variables. 지역 변수 선언은 형식 이름, 변수 이름을 지정하며 초기 값을 지정할 수도 있습니다.A local variable declaration specifies a type name, a variable name, and possibly an initial value. 다음 예제에서는 초기 값이 0인 지역 변수 i와 초기 값이 없는 지역 변수 j를 선언합니다.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#에서는 해당 값을 얻기 위해 먼저 로컬 변수를 명확 하게 할당해야 합니다.C# requires a local variable to be definitely assigned before its value can be obtained. 예를 들어 이전 i의 선언에 초기 값이 포함되지 않으면 컴파일러는 i의 후속 사용에 대해 오류를 보고합니다. i는 프로그램에서 해당 시점에 명확하게 할당되지 않은 것이기 때문입니다.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.

메서드는 return 문을 사용하여 해당 호출자에게 컨트롤을 반환할 수 있습니다.A method can use return statements to return control to its caller. void를 반환하는 메서드에서 return 문은 식을 지정할 수 없습니다.In a method returning void, return statements cannot specify an expression. void이 아닌를 return 반환 하는 메서드에서는 반환 값을 계산 하는 식을 포함 해야 합니다.In a method returning non-void, return statements must include an expression that computes the return value.

정적 및 인스턴스 메서드Static and instance methods

static 한정자를 사용 하 여 선언 된 메서드는 정적 메서드입니다.A method declared with a static modifier is a static method. 정적 메서드는 특정 인스턴스에 작동하지 않고 정적 멤버에 직접적으로만 액세스할 수 있습니다.A static method does not operate on a specific instance and can only directly access static members.

static 한정자 없이 선언 된 메서드는 인스턴스 메서드입니다.A method declared without a static modifier is an instance method. 인스턴스 메서드는 특정 인스턴스에 작동하며 정적 및 인스턴스 멤버 둘 다에 액세스할 수 있습니다.An instance method operates on a specific instance and can access both static and instance members. 인스턴스 메서드가 호출된 인스턴스는 this로 명시적으로 액세스할 수 있습니다.The instance on which an instance method was invoked can be explicitly accessed as this. 정적 메서드에서 this를 참조하면 오류가 발생합니다.It is an error to refer to this in a static method.

다음 Entity 클래스에는 정적 멤버와 인스턴스 멤버가 모두 있습니다.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;
    }
}

Entity 인스턴스에는 일련 번호(및 여기에 표시되지 않는 일부 정보)가 포함되어 있습니다.Each Entity instance contains a serial number (and presumably some other information that is not shown here). Entity 생성자(인스턴스 메서드와 유사함)는 사용 가능한 다음 일련 번호를 사용하여 새 인스턴스를 초기화합니다.The Entity constructor (which is like an instance method) initializes the new instance with the next available serial number. 생성자가 인스턴스 멤버이기 때문에 serialNo 인스턴스 필드 및 nextSerialNo 정적 필드 둘 다에 액세스하도록 허용됩니다.Because the constructor is an instance member, it is permitted to access both the serialNo instance field and the nextSerialNo static field.

GetNextSerialNoSetNextSerialNo 정적 메서드는 nextSerialNo 정적 필드에 액세스할 수 있지만 serialNo 인스턴스 필드에 직접 액세스하면 오류가 발생합니다.The 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.

다음 예제에서는 사용 된 Entity 클래스입니다.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"
    }
}

SetNextSerialNoGetNextSerialNo 정적 메서드는 클래스에 대해 호출되지만 GetSerialNo 인스턴스 메서드는 클래스의 인스턴스에 대해 호출됩니다.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.

가상, 재정의 및 추상 메서드Virtual, override, and abstract methods

인스턴스 메서드 선언에 virtual 한정자가 포함되면 해당 메서드를 가상 메서드라고 합니다.When an instance method declaration includes a virtual modifier, the method is said to be a virtual method. 한정자가 virtual 없는 경우이 메서드는 비가상 메서드라고 합니다.When no virtual modifier is present, the method is said to be a non-virtual method.

가상 메서드가 호출되면 호출이 발생하는 인스턴스의 런타임 형식에 따라 호출할 실제 메서드 구현이 결정됩니다.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. 비가상 메서드 호출에서는 인스턴스의 컴파일 타임 형식이 결정 요인입니다.In a nonvirtual method invocation, the compile-time type of the instance is the determining factor.

가상 메서드는 파생된 클래스에서 재정의될 수 있습니다.A virtual method can be overridden in a derived class. 인스턴스 메서드 선언에 한정자가 override 포함 된 경우 메서드는 동일한 서명으로 상속 된 가상 메서드를 재정의 합니다.When an instance method declaration includes an override modifier, the method overrides an inherited virtual method with the same signature. 가상 메서드 선언은 새 메서드를 도입하지만 재정의 메서드 선언은 해당 메서드의 새 구현을 제공하여 기존의 상속된 가상 메서드를 특수화합니다.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.

추상 메서드는 구현이 없는 가상 메서드입니다.An abstract method is a virtual method with no implementation. 추상 메서드는 abstract 한정자를 사용 하 여 선언 되 고도 선언 abstract된 클래스 에서만 허용 됩니다.An abstract method is declared with the abstract modifier and is permitted only in a class that is also declared abstract. 추상 메서드는 모든 비추상 파생 클래스에서 재정의해야 합니다.An abstract method must be overridden in every non-abstract derived class.

다음 예제에서는 식 트리 노드를 나타내는 추상 클래스 Expression와 상수, 변수 참조 및 산술 연산에 대한 식 트리 노드를 구현하는 세 개의 파생 클래스 Constant, VariableReferenceOperation을 선언합니다.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. 이는와 유사 하지만 식 트리 형식에서 도입 된 식 트리 형식과 혼동 하지 않아야 합니다.(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");
    }
}

이전의 4개 클래스는 산술 연산자를 모델링하는 데 사용할 수 있습니다.The previous four classes can be used to model arithmetic expressions. 예를 들어 이러한 클래스의 인스턴스를 사용할 경우 식 x + 3을 다음과 같이 나타낼 수 있습니다.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));

Expression 인스턴스의 Evaluate 메서드는 지정된 식을 계산하고 double 값을 생성하기 위해 호출됩니다.The Evaluate method of an Expression instance is invoked to evaluate the given expression and produce a double value. 메서드는 변수 이름 (항목의 Hashtable 키)과 값 (항목의 값)을 포함 하는를 인수로 사용 합니다.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 는 가상 추상 메서드이므로 추상이 아닌 파생 클래스에서 실제 구현을 제공 하기 위해 재정의 해야 하는 것을 의미 합니다.The Evaluate method is a virtual abstract method, meaning that non-abstract derived classes must override it to provide an actual implementation.

EvaluateConstant 구현은 단순히 저장된 상수를 반환합니다.A Constant's implementation of Evaluate simply returns the stored constant. VariableReference의 구현은 hashtable에서 변수 이름을 조회 하 고 결과 값을 반환 합니다.A VariableReference's implementation looks up the variable name in the hashtable and returns the resulting value. Operation의 구현은 먼저 왼쪽 및 오른쪽 피연산자를 계산하고(재귀적으로 해당 Evaluate 메서드 호출) 지정된 산술 연산을 수행합니다.An Operation's implementation first evaluates the left and right operands (by recursively invoking their Evaluate methods) and then performs the given arithmetic operation.

다음 프로그램에서는 Expression 클래스를 사용하여 xy의 다른 값에 대해 식 x * (y + 2)를 계산합니다.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"
    }
}

메서드 오버로드Method overloading

메서드 오버로드는 동일한 클래스가 고유한 시그니처를 갖는 한, 동일한 이름을 갖도록 허용합니다.Method overloading permits multiple methods in the same class to have the same name as long as they have unique signatures. 오버로드된 메서드의 호출을 컴파일할 때 컴파일러는 오버로드 확인을 사용하여 호출할 특정 메서드를 결정합니다.When compiling an invocation of an overloaded method, the compiler uses overload resolution to determine the specific method to invoke. 오버로드 확인은 인수와 가장 적합하게 일치하는 단일 메서드를 찾으며, 최상의 일치 메서드를 찾을 수 있는 경우 오류를 보고합니다.Overload resolution finds the one method that best matches the arguments or reports an error if no single best match can be found. 다음 예제에서는 실제로 진행되는 오버로드 확인을 보여 줍니다.The following example shows overload resolution in effect. Main 메서드의 각 호출에 대한 주석은 실제로 호출되는 메서드를 보여 줍니다.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)
    }
}

예제와 같이, 인수를 정확한 매개 변수 형식으로 명시적으로 캐스팅하거나 형식 인수를 명시적으로 제공하여 항상 특정 메서드를 선택할 수 있습니다.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.

기타 함수 멤버Other function members

실행 코드를 포함하는 멤버를 통칭하여 클래스의 함수 멤버라고 합니다.Members that contain executable code are collectively known as the function members of a class. 이전 섹션에서는 함수 멤버의 기본 종류인 메서드에 대해 설명합니다.The preceding section describes methods, which are the primary kind of function members. 이 섹션에서는 생성자, 속성, 인덱서, 이벤트, C#연산자 및 소멸자에서 지 원하는 다른 종류의 함수 멤버에 대해 설명 합니다.This section describes the other kinds of function members supported by C#: constructors, properties, indexers, events, operators, and destructors.

다음 코드에서는 개체의 growable 목록을 구현 List<T>하는 라는 제네릭 클래스를 보여 줍니다.The following code shows a generic class called List<T>, which implements a growable list of objects. 이 클래스는 함수 멤버의 가장 일반적인 몇 가지 예제를 포함합니다.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);
    }
}

생성자Constructors

C#은 인스턴스 및 정적 생성자를 모두 지원합니다.C# supports both instance and static constructors. 인스턴스 생성자는 클래스의 인스턴스를 초기화하는 데 필요한 작업을 구현하는 멤버입니다.An instance constructor is a member that implements the actions required to initialize an instance of a class. 정적 생성자는 처음 로드될 때 클래스 자체를 인스턴스화하는 데 필요한 작업을 구현하는 멤버입니다.A static constructor is a member that implements the actions required to initialize a class itself when it is first loaded.

생성자는 반환 형식이 없고 포함하는 클래스와 동일한 이름을 갖는 메서드처럼 선언됩니다.A constructor is declared like a method with no return type and the same name as the containing class. 생성자 선언에 한정자가 static 포함 된 경우 정적 생성자를 선언 합니다.If a constructor declaration includes a static modifier, it declares a static constructor. 그렇지 않으면 인스턴스 생성자를 선언합니다.Otherwise, it declares an instance constructor.

인스턴스 생성자를 오버 로드할 수 있습니다.Instance constructors can be overloaded. 예를 들어 List<T> 클래스는 2개의 인스턴스 생성자, 즉, 매개 변수가 없는 생성자와 int 매개 변수를 취하는 생성자를 선언합니다.For example, the List<T> class declares two instance constructors, one with no parameters and one that takes an int parameter. 인스턴스 생성자는 new 연산자를 사용하여 호출됩니다.Instance constructors are invoked using the new operator. 다음 문은 List 클래스의 각 List<string> 생성자를 사용 하 여 두 개의 인스턴스를 할당 합니다.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);

다른 멤버와 달리 인스턴스 생성자는 상속되지 않으며 클래스에는 클래스에서 실제로 선언된 인스턴스 생성자만 포함됩니다.Unlike other members, instance constructors are not inherited, and a class has no instance constructors other than those actually declared in the class. 클래스에 대해 인스턴스 생성자가 제공되지 않으면 매개 변수가 없는 빈 인스턴스 생성자가 자동으로 제공됩니다.If no instance constructor is supplied for a class, then an empty one with no parameters is automatically provided.

속성Properties

속성은 필드의 기본 확장입니다.Properties are a natural extension of fields. 둘 다 연결된 형식으로 명명되는 멤버이며, 필드 및 속성에 액세스하는 구문은 동일합니다.Both are named members with associated types, and the syntax for accessing fields and properties is the same. 그러나 필드와 달리 속성은 스토리지 위치를 명시하지 않습니다.However, unlike fields, properties do not denote storage locations. 대신, 속성에는 해당 값을 읽거나 쓸 때 실행될 문을 지정하는 접근자가 있습니다.Instead, properties have accessors that specify the statements to be executed when their values are read or written.

속성은 필드 처럼 선언 됩니다 get . 단, 선언은 접근자 및/ set 또는 구분 기호 { 사이에 } 쓰여진 접근자 및/또는 접근자를 사용 하 여 끝나는 대신 세미콜론으로 끝나지 않습니다.A property is declared like a field, except that the declaration ends with a get accessor and/or a set accessor written between the delimiters { and } instead of ending in a semicolon. get get 접근자 set와 접근자가 모두 있는 속성은 읽기/쓰기 속성 이며 접근자만 있는 속성은 읽기 전용 속성 이며 접근자만 있는 속성은입니다. set 쓰기 전용 속성입니다.A property that has both a get accessor and a set accessor is a read-write property, a property that has only a get accessor is a read-only property, and a property that has only a set accessor is a write-only property.

접근자 get 는 속성 형식의 반환 값이 있는 매개 변수가 없는 메서드에 해당 합니다.A get accessor corresponds to a parameterless method with a return value of the property type. 할당의 대상이 아닌 식 get 에서 속성을 참조 하는 경우 속성의 접근자가 호출 되어 속성의 값을 계산 합니다.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.

접근자 set 는 라는 value 단일 매개 변수가 있고 반환 형식이 없는 메서드에 해당 합니다.A set accessor corresponds to a method with a single parameter named value and no return type. 속성이 할당의 대상이 나 또는 ++ --의 피연산자로 참조 되는 경우 접근자는 set 새 값을 제공 하는 인수를 사용 하 여 호출 됩니다.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.

List<T> 클래스는 각각 읽기 전용 및 읽기/쓰기 특성을 갖는 두 개의 속성 CountCapacity를 선언합니다.The List<T> class declares two properties, Count and Capacity, which are read-only and read-write, respectively. 다음은 이러한 속성 사용의 예입니다.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

필드 및 메서드와 마찬가지로, C#은 인스턴스 속성 및 정적 속성을 모두 지원합니다.Similar to fields and methods, C# supports both instance properties and static properties. 정적 속성은 static 한정자를 사용 하 여 선언 되 고, 인스턴스 속성은 포함 하지 않고 선언 됩니다.Static properties are declared with the static modifier, and instance properties are declared without it.

속성의 접근자는 가상일 수 있습니다.The accessor(s) of a property can be virtual. 속성 선언에 virtual, abstract, 또는 override 한정자가 포함되면 속성의 접근자에 적용됩니다.When a property declaration includes a virtual, abstract, or override modifier, it applies to the accessor(s) of the property.

인덱서Indexers

인덱서는 개체가 배열과 같은 방식으로 인덱싱될 수 있도록 하는 멤버입니다.An indexer is a member that enables objects to be indexed in the same way as an array. 인덱서는 this과(와) 구분 기호 [] 사이에 작성된 매개 변수 목록을 합쳐서 구성원 이름으로 사용한다는 점을 제외하고 속성처럼 선언됩니다.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 ]. 매개 변수는 인덱서의 접근자에서 사용할 수 있습니다.The parameters are available in the accessor(s) of the indexer. 속성과 마찬가지로 인덱서는 읽기/쓰기, 읽기 전용 및 쓰기 전용일 수 있으며 인덱서의 접근자는 가상일 수 있습니다.Similar to properties, indexers can be read-write, read-only, and write-only, and the accessor(s) of an indexer can be virtual.

List 클래스는 int 매개 변수를 사용하는 단일 읽기/쓰기 인덱서를 선언합니다.The List class declares a single read-write indexer that takes an int parameter. 인덱서는 List 인스턴스를 int 값으로 인덱싱할 수 있도록 합니다.The indexer makes it possible to index List instances with int values. 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();
}

인덱서는 오버로드될 수 있습니다. 즉, 해당 매개 변수의 수와 형식이 다를 경우 한 클래스가 여러 인덱서를 선언할 수 있습니다.Indexers can be overloaded, meaning that a class can declare multiple indexers as long as the number or types of their parameters differ.

이벤트Events

이벤트는 클래스 또는 개체가 알림을 제공할 수 있도록 하는 멤버입니다.An event is a member that enables a class or object to provide notifications. 이벤트는 선언에 event 키워드가 포함 되 고 형식이 대리자 형식 이어야 한다는 점만 제외 하 고 필드 처럼 선언 됩니다.An event is declared like a field except that the declaration includes an event keyword and the type must be a delegate type.

이벤트 멤버를 선언하는 클래스 내에서 이벤트는 대리자 형식의 필드처럼 동작합니다(이벤트가 추상이 아니고 접근자를 선언하지 않을 경우).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). 필드는 이벤트에 추가된 이벤트 처리기를 나타내는 대리자에 대한 참조를 저장합니다.The field stores a reference to a delegate that represents the event handlers that have been added to the event. 이벤트 핸들이 없는 경우 필드 null는입니다.If no event handles are present, the field is null.

List<T> 클래스는 Changed라는 단일 이벤트 멤버를 선언합니다. 이것은 새 항목이 목록에 추가되었음을 나타냅니다.The List<T> class declares a single event member called Changed, which indicates that a new item has been added to the list. 이벤트 Changed 는 이벤트가 발생 하는지 여부 OnChanged null 를 먼저 확인 하는 가상 메서드에 의해 발생 합니다. 즉, 처리기가 없음을 의미 합니다.The Changed event is raised by the OnChanged virtual method, which first checks whether the event is null (meaning that no handlers are present). 이벤트 발생 개념은 이벤트가 나타내는 대리자를 호출하는 것과 정확히 동일하므로 이벤트 발생을 위한 특수한 언어 구문은 없습니다.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.

클라이언트는 이벤트 처리기를 통해 이벤트에 반응합니다.Clients react to events through event handlers. 이벤트 처리기는 += 연산자를 사용하여 추가되고, -= 연산자를 사용하여 제거됩니다.Event handlers are attached using the += operator and removed using the -= operator. 다음 예제에서는 이벤트 처리기를 List<string>Changed 이벤트에 추가합니다.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"
    }
}

이벤트의 기본 스토리지를 제어하려고 하는 고급 시나리오의 경우 이벤트 선언에서 속성의 set 접근자와 비슷한 addremove 접근자를 명시적으로 제공할 수 있습니다.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.

연산자Operators

연산자는 클래스 인스턴스에 특정 식 연산자를 적용하는 것의 의미를 정의하는 멤버입니다.An operator is a member that defines the meaning of applying a particular expression operator to instances of a class. 세 가지 종류의 연산자, 즉, 단항 연산자, 이항 연산자 및 변환 연산자를 정의할 수 있습니다.Three kinds of operators can be defined: unary operators, binary operators, and conversion operators. 모든 연산자는 publicstatic으로 선언해야 합니다.All operators must be declared as public and static.

List<T> 클래스는 두 가지 연산자인 operator==operator!=를 선언하므로 해당 연산자를 List 인스턴스에 적용하는 새로운 의미를 식에 지정합니다.The List<T> class declares two operators, operator== and operator!=, and thus gives new meaning to expressions that apply those operators to List instances. 특히 연산자는 해당 List<T> Equals 메서드를 사용 하 여 각 포함 된 개체를 비교 하는 것 처럼 두 인스턴스의 같음을 정의 합니다.Specifically, the operators define equality of two List<T> instances as comparing each of the contained objects using their Equals methods. 다음 예제에서는 == 연산자를 사용하여 두 List<int> 인스턴스를 비교합니다.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"
    }
}

두 목록은 같은 순서로 같은 값을 갖는 동일한 수의 개체를 포함하므로 첫 번째 Console.WriteLineTrue를 출력합니다.The first Console.WriteLine outputs True because the two lists contain the same number of objects with the same values in the same order. List<T>에서 operator==이 정의되지 않았으면 ab은 다른 List<int> 인스턴스를 참조하므로 첫 번째 Console.WriteLineFalse를 출력합니다.Had List<T> not defined operator==, the first Console.WriteLine would have output False because a and b reference different List<int> instances.

소멸자Destructors

소멸자 는 클래스의 인스턴스를 소멸 시키는 데 필요한 작업을 구현 하는 멤버입니다.A destructor is a member that implements the actions required to destruct an instance of a class. 소멸자에는 매개 변수를 사용할 수 없으며, 액세스 가능성 한정자를 가질 수 없으며 명시적으로 호출할 수 없습니다.Destructors cannot have parameters, they cannot have accessibility modifiers, and they cannot be invoked explicitly. 인스턴스의 소멸자는 가비지 수집 중에 자동으로 호출 됩니다.The destructor for an instance is invoked automatically during garbage collection.

가비지 수집기는 개체를 수집 하 고 소멸자를 실행 하는 시기를 결정 하는 데 사용할 수 있는 광범위 한 위도입니다.The garbage collector is allowed wide latitude in deciding when to collect objects and run destructors. 특히 소멸자 호출의 타이밍은 결정적이 아니며 소멸자가 모든 스레드에서 실행 될 수 있습니다.Specifically, the timing of destructor invocations is not deterministic, and destructors may be executed on any thread. 이러한 다른 이유 때문에 클래스는 다른 솔루션이 불가능 한 경우에만 소멸자를 구현 해야 합니다.For these and other reasons, classes should implement destructors only when no other solutions are feasible.

using 문은 개체 소멸을 위한 더 나은 방법을 제공합니다.The using statement provides a better approach to object destruction.

구조체Structs

구조체는 클래스처럼 데이터 멤버 및 함수 멤버를 포함할 수 있는 데이터 구조이지만 값 형식이며 힙 할당이 필요하지 않다는 점이 클래스와 다릅니다.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. 구조체 형식의 변수는 구조체의 데이터를 직접 저장하지만 클래스 형식의 변수는 동적으로 할당된 개체에 대한 참조를 저장합니다.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. 구조체 형식은 사용자 지정 상속을 지원하지 않으며 모든 구조체 형식은 object 형식에서 암시적으로 상속됩니다.Struct types do not support user-specified inheritance, and all struct types implicitly inherit from type object.

구조체는 값 의미 체계를 갖는 작은 데이터 구조에 특히 유용합니다.Structs are particularly useful for small data structures that have value semantics. 복소수, 좌표계의 점 또는 사전의 키-값 쌍이 모두 구조체의 좋은 예입니다.Complex numbers, points in a coordinate system, or key-value pairs in a dictionary are all good examples of structs. 작은 데이터 구조에 클래스 대신 구조체를 사용하는 것은 애플리케이션이 사용하는 메모리 할당 수에서 큰 차이를 보일 수 있습니다.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. 예를 들어 다음 프로그램은 100개의 점 배열을 만들고 초기화합니다.For example, the following program creates and initializes an array of 100 points. Point가 클래스로 구현될 경우 배열에 대해 1개, 100개 요소에 대해 각각 1개씩 101개의 별도 개체가 인스턴스화됩니다.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);
    }
}

또 다른 방법은 구조체를 Point 만드는 것입니다.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;
    }
}

이제 1개의 개체만 인스턴스화되고(배열에 대해 1개) Point 인스턴스는 배열에 인라인으로 저장됩니다.Now, only one object is instantiated—the one for the array—and the Point instances are stored in-line in the array.

구조체 생성자는 new 연산자로 호출되지만 메모리가 할당된다는 것을 의미하지는 않습니다.Struct constructors are invoked with the new operator, but that does not imply that memory is being allocated. 개체를 동적으로 할당하고 그에 대한 참조를 반환하는 대신, 구조체 생성자는 단순히 구조체 값 자체(일반적으로 스택의 임시 위치에 있음)를 반환하며 이 값은 필요할 때 복사됩니다.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.

클래스에서는 두 가지 변수가 같은 개체를 참조할 수 있으므로 한 변수에 대한 작업이 다른 변수에서 참조하는 개체에 영향을 미칠 수 있습니다.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. 구조체에서는 변수 각각에 데이터의 자체 사본이 들어 있으며 한 변수의 작업이 다른 변수에 영향을 미칠 수 없습니다.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. 예를 들어, 다음 코드 조각에 의해 생성 된 출력은가 Point 클래스 인지 구조체 인지에 따라 달라 집니다.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);

Point 클래스 이면 출력은와 20 b 가 같은 개체 a 를 참조 하기 때문입니다.If Point is a class, the output is 20 because a and b reference the same object. Point struct 인 경우는 a10 b 대 한 할당이 값의 복사본을 만들지만이 복사본은에 대 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.

이전 예제에는 구조체의 제한 사항 중 두 가지를 집중적으로 보여 줍니다.The previous example highlights two of the limitations of structs. 첫째, 일반적으로 전체 구조체를 복사하는 것이 개체 참조를 복사하는 것보다 덜 효율적이므로 대입 및 값 매개 변수 전달이 참조 형식보다 덜 경제적일 수 있습니다.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. 둘째, refout 매개 변수를 제외하고, 구조체에 대한 참조를 만들 수 없으므로 다양한 상황에서 사용하는 것이 불가능합니다.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.

배열Arrays

배열은 계산된 인덱스를 통해 액세스되는 여러 변수를 포함하는 데이터 구조입니다.An array is a data structure that contains a number of variables that are accessed through computed indices. 배열에 포함된 변수, 즉 배열의 요소라고도 하는 배열은 모두 같은 형식이며, 이 형식을 배열의 요소 형식이라고 합니다.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.

배열 형식은 참조 형식이고 배열 변수의 선언은 배열 인스턴스에 대한 참조를 위한 공간을 설정합니다.Array types are reference types, and the declaration of an array variable simply sets aside space for a reference to an array instance. 실제 배열 인스턴스는 런타임에 연산자를 new 사용 하 여 동적으로 생성 됩니다.Actual array instances are created dynamically at run-time using the new operator. 작업 new 은 새 배열 인스턴스의 길이 를 지정 하며,이는 인스턴스의 수명 동안 고정 됩니다.The new operation specifies the length of the new array instance, which is then fixed for the lifetime of the instance. 배열 요소의 인덱스 범위는 0에서 Length - 1 사이입니다.The indices of the elements of an array range from 0 to Length - 1. new 연산자는 배열의 요소를 모든 숫자 형식에 대해 0이고, 모든 참조 형식에 대해 null인 기본값으로 자동으로 초기화합니다.The 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.

다음 예제에서는 int 요소의 배열을 만들고, 배열을 초기화하고, 배열의 콘텐츠를 출력합니다.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]);
        }
    }
}

이 예제에서는 1차원 배열을 만들고 작업을 수행합니다.This example creates and operates on a single-dimensional array. C#에서는 다차원 배열s을 지원하지 않습니다.C# also supports multi-dimensional arrays. 배열 형식의 순위라고도 하는 배열 형식의 차원 수는 배열 형식의 대괄호 사이에 사용된 쉼표 수에 1을 더한 값입니다.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. 다음 예에서는 1 차원, 2 차원 및 3 차원 배열을 할당 합니다.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];

a1 배열에는 10개의 요소가 들어 있고 a2 배열에는 50(10 × 5)개의 요소가 들어 있고 a3 배열에는 100(10 × 5 × 2)개 요소가 들어 있습니다.The a1 array contains 10 elements, the a2 array contains 50 (10 × 5) elements, and the a3 array contains 100 (10 × 5 × 2) elements.

배열의 요소 형식은 배열 형식을 비롯한 어떤 형식도 될 수 있습니다.The element type of an array can be any type, including an array type. 배열 형식의 요소가 있는 배열을 가변 배열이라고도 합니다. 요소 배열의 길이가 항상 동일할 필요는 없기 때문입니다.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. 다음 예제에서는 int 배열의 배열을 할당합니다.The following example allocates an array of arrays of int:

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

첫 번째 줄은 형식이 int[]이고 초기 값이 null인 3개 요소가 있는 배열을 만듭니다.The first line creates an array with three elements, each of type int[] and each with an initial value of null. 다음 줄은 가변 길이의 개별 배열 인스턴스에 대한 참조로 3개 요소를 초기화합니다.The subsequent lines then initialize the three elements with references to individual array instances of varying lengths.

연산자 new 는 구분 { 기호와 }사이에 쓰여진 식의 목록 인 배열 이니셜라이저를 사용 하 여 배열 요소의 초기 값을 지정할 수 있도록 허용 합니다.The 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 }. 다음 예제에서는 3개 요소로 int[]를 할당하고 초기화합니다.The following example allocates and initializes an int[] with three elements.

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

배열의 길이는와 { }사이의 식 수에서 유추 됩니다.Note that the length of the array is inferred from the number of expressions between { and }. 지역 변수 및 필드 선언은 배열 형식을 다시 시작할 필요가 없도록 좀 더 줄일 수 있습니다.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};

앞의 두 예제는 다음 예제와 동일합니다.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;

인터페이스Interfaces

인터페이스는 클래스 및 구조체에서 구현될 수 있는 계약을 정의합니다.An interface defines a contract that can be implemented by classes and structs. 인터페이스는 메서드, 속성, 이벤트 및 인덱서를 포함할 수 있습니다.An interface can contain methods, properties, events, and indexers. 인터페이스는 정의하는 멤버의 구현을 제공하지 않으며 단순히 인터페이스를 구현하는 클래스 또는 구조체에서 제공해야 하는 멤버를 지정합니다.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.

인터페이스는 다중 상속을 사용할 수 있습니다.Interfaces may employ multiple inheritance. 다음 예제에서 인터페이스 IComboBoxITextBoxIListBox를 둘 다 상속합니다.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 {}

클래스 및 구조체는 여러 인터페이스를 구현할 수 있습니다.Classes and structs can implement multiple interfaces. 다음 예제에서 클래스 EditBoxIControlIDataBound를 둘 다 구현합니다.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) {...}
}

클래스 또는 구조체가 특정 인터페이스를 구현하는 경우 해당 클래스 또는 구조체의 인스턴스를 해당 인터페이스 형식으로 암시적으로 변환할 수 있습니다.When a class or struct implements a particular interface, instances of that class or struct can be implicitly converted to that interface type. For example

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

인스턴스가 정적으로 특정 인터페이스를 구현하는 것으로 알려지지 않은 경우 동적 형식 캐스팅을 사용할 수 있습니다.In cases where an instance is not statically known to implement a particular interface, dynamic type casts can be used. 예를 들어 다음 문은 동적 형식 캐스팅을 사용 하 여 개체의 IControlIDataBound 인터페이스 구현을 가져옵니다.For example, the following statements use dynamic type casts to obtain an object's IControl and IDataBound interface implementations. 개체 EditBox의 실제 형식이 이기 때문에 캐스팅이 성공 합니다.Because the actual type of the object is EditBox, the casts succeed.

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

이전 EditBox IDataBound public 클래스 IControl 에서 인터페이스 의Bind 메서드와 인터페이스의 메서드는 멤버를 사용 하 여 구현 됩니다. PaintIn 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#는 클래스 또는 구조체에서 멤버 public를 만들 수 없도록 하는 명시적 인터페이스 멤버 구현도 지원 합니다.C# also supports explicit interface member implementations, using which the class or struct can avoid making the members public. 명시적 인터페이스 멤버 구현은 정규화된 인터페이스 멤버 이름을 사용하여 작성됩니다.An explicit interface member implementation is written using the fully qualified interface member name. 예를 들어 EditBox 클래스는 다음과 같이 명시적 인터페이스 멤버 구현을 사용하여 IControl.PaintIDataBound.Bind 메서드를 구현할 수 있습니다.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) {...}
}

명시적 인터페이스 멤버는 인터페이스 형식을 통해서만 액세스할 수 있습니다.Explicit interface members can only be accessed via the interface type. IControl.Paint 예를 들어 이전 EditBox 클래스에서 제공 하는의 구현은 먼저 IControl 인터페이스 형식에 대 한 EditBox 참조를 변환 하는 경우에만 호출할 수 있습니다.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

열거형Enums

열거형 형식은 명명된 상수 집합을 갖는 고유 값 형식입니다.An enum type is a distinct value type with a set of named constants. 다음 예제 Color 에서는 세 개의 상수 RedGreen, 및 Blue가 포함 된 열거형 형식을 선언 하 고 사용 합니다.The following example declares and uses an enum type named Color with three constant values, Red, Green, and Blue.

using System;

enum Color
{
    Red,
    Green,
    Blue
}

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

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

각 열거형 형식에는 열거형 형식의 기본 형식 이라고 하는 해당 정수 형식이 있습니다.Each enum type has a corresponding integral type called the underlying type of the enum type. 내부 형식을 명시적으로 선언 하지 않는 열거형 형식에는의 int기본 형식이 있습니다.An enum type that does not explicitly declare an underlying type has an underlying type of int. 열거형 형식의 저장소 형식 및 가능한 값의 범위는 해당 기본 형식에 의해 결정 됩니다.An enum type's storage format and range of possible values are determined by its underlying type. 열거형 형식이 사용할 수 있는 값 집합은 열거형 멤버로 제한 되지 않습니다.The set of values that an enum type can take on is not limited by its enum members. 특히 열거형의 기본 형식 값은 열거형 형식으로 캐스팅 될 수 있으며 해당 열거형 형식의 유효한 고유 값입니다.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.

다음 예제에서는의 Alignment sbyte기본 형식을 사용 하 여 라는 열거형 형식을 선언 합니다.The following example declares an enum type named Alignment with an underlying type of sbyte.

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

앞의 예제와 같이 열거형 멤버 선언에는 멤버의 값을 지정 하는 상수 식이 포함 될 수 있습니다.As shown by the previous example, an enum member declaration can include a constant expression that specifies the value of the member. 각 열거형 멤버에 대 한 상수 값은 열거형의 기본 형식 범위에 속해야 합니다.The constant value for each enum member must be in the range of the underlying type of the enum. 열거형 멤버 선언에서 값을 명시적으로 지정 하지 않으면 멤버에 값 0 (열거형 형식의 첫 번째 멤버인 경우) 또는 열거형 멤버 앞에 있는 형식 (열거형)의 값이 지정 됩니다.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.

형식 캐스팅을 사용 하 여 열거형 값을 정수 값으로 변환 하거나 그 반대로 변환할 수 있습니다.Enum values can be converted to integral values and vice versa using type casts. For example

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

열거형 형식의 기본값은 열거형 형식으로 변환 된 정수 값 0입니다.The default value of any enum type is the integral value zero converted to the enum type. 변수가 기본값으로 자동 초기화 되는 경우 열거형 형식의 변수에 지정 된 값입니다.In cases where variables are automatically initialized to a default value, this is the value given to variables of enum types. 열거형 형식의 기본값을 쉽게 사용할 수 있도록 리터럴 0 은 암시적으로 열거형 형식으로 변환 합니다.In order for the default value of an enum type to be easily available, the literal 0 implicitly converts to any enum type. 따라서 다음이 허용됩니다.Thus, the following is permitted.

Color c = 0;

대리자Delegates

대리자는 특정 매개 변수 목록 및 반환 형식이 있는 메서드에 대한 참조를 나타내는 형식입니다.A delegate type represents references to methods with a particular parameter list and return type. 대리자는 메서드를 변수에 할당되고 매개 변수로 전달될 수 있는 엔터티로 취급할 수 있도록 합니다.Delegates make it possible to treat methods as entities that can be assigned to variables and passed as parameters. 또한 대리자는 다른 언어에 나오는 함수 포인터의 개념과 비슷하지만 함수 포인터와 달리 대리자는 개체 지향적이며 형식 안전 방식입니다.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.

다음 예제에서는 Function라는 대리자 형식을 선언하고 사용합니다.The following example declares and uses a delegate type named Function.

using System;

delegate double Function(double x);

class Multiplier
{
    double factor;

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

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

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

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

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

Function 대리자 형식의 인스턴스는 double 인수를 사용하고 double 값을 반환하는 메서드를 참조할 수 있습니다.An instance of the Function delegate type can reference any method that takes a double argument and returns a double value. 메서드 Apply 는 지정 Function 된를의 double[]요소에 적용 하 여 결과와 double[] 함께을 반환 합니다.The Apply method applies a given Function to the elements of a double[], returning a double[] with the results. Main 메서드에서 Apply는 세 가지 다른 함수를 double[]에 적용하는 데 사용됩니다.In the Main method, Apply is used to apply three different functions to a double[].

대리자는 정적 메서드(예: 이전 예제의 Square 또는 Math.Sin) 또는 인스턴스 메서드(예: 이전 예제의 m.Multiply)를 참조할 수 있습니다.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). 인스턴스 메서드를 참조하는 대리자는 특정 개체도 참조하며, 인스턴스 메서드가 대리자를 통해 호출되는 경우 해당 개체도 이 호출에서 this가 됩니다.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.

또한 즉석에서 만들어지는 "인라인 메서드"인 익명 함수를 사용하여 대리자를 만들 수도 있습니다.Delegates can also be created using anonymous functions, which are "inline methods" that are created on the fly. 익명 함수는 주변 메서드의 지역 변수를 볼 수 있습니다.Anonymous functions can see the local variables of the surrounding methods. 따라서 위의 승수 예제는 클래스를 Multiplier 사용 하지 않고 더 쉽게 작성할 수 있습니다.Thus, the multiplier example above can be written more easily without using a Multiplier class:

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

대리자의 흥미롭고 유용한 속성은 참조하는 메서드의 클래스를 알지 못하거나 관심을 두지 않는다는 것입니다. 참조되는 메서드가 대리자와 동일한 매개 변수 및 반환 형식을 갖는다는 것만 중요합니다.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.

특성Attributes

C# 프로그램의 형식, 멤버 및 기타 엔터티는 동작의 특정 측면을 제어하는 한정자를 지원합니다.Types, members, and other entities in a C# program support modifiers that control certain aspects of their behavior. 예를 들어 메서드의 액세스 가능성은 public, protected, internalprivate 한정자를 사용하여 제어됩니다.For example, the accessibility of a method is controlled using the public, protected, internal, and private modifiers. C#은 선언적 정보의 사용자 정의 형식을 프로그램 엔터티에 연결하고 런타임에 검색할 수 있도록 이러한 기능을 일반화합니다.C# generalizes this capability such that user-defined types of declarative information can be attached to program entities and retrieved at run-time. 프로그램은 특성을 정의하고 사용하여 이러한 추가적인 선언적 정보를 지정합니다.Programs specify this additional declarative information by defining and using attributes.

다음 예제에서는 관련 설명서에 대한 링크를 제공하기 위해 프로그램 엔터티에 배치될 수 있는 HelpAttribute 특성을 선언합니다.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; }
    }
}

모든 특성 클래스는 .NET Framework에서 System.Attribute 제공 하는 기본 클래스에서 파생 됩니다.All attribute classes derive from the System.Attribute base class provided by the .NET Framework. 연결된 선언 바로 앞에 대괄호로 묶은 특성 이름을 인수와 함께 적용할 수 있습니다.Attributes can be applied by giving their name, along with any arguments, inside square brackets just before the associated declaration. 특성 이름이에서 Attribute종료 되는 경우 특성을 참조 하는 경우 이름의 해당 부분을 생략할 수 있습니다.If an attribute's name ends in Attribute, that part of the name can be omitted when the attribute is referenced. 예를 들어 HelpAttribute 특성을 다음과 같이 사용할 수 있습니다.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) {}
}

이 예제에서는를 HelpAttribute Widget 클래스에HelpAttribute , 다른 클래스의 메서드에연결합니다.DisplayThis example attaches a HelpAttribute to the Widget class and another HelpAttribute to the Display method in the class. 특성 클래스의 공용 생성자는 프로그램 엔터티에 특성을 추가할 때 제공해야 하는 정보를 제어합니다.The public constructors of an attribute class control the information that must be provided when the attribute is attached to a program entity. 특성 클래스의 공용 읽기/쓰기 속성을 참조하여 추가 정보를 제공할 수 있습니다(예: 앞에 나온 Topic 속성 참조).Additional information can be provided by referencing public read-write properties of the attribute class (such as the reference to the Topic property previously).

다음 예제에서는 리플렉션을 사용 하 여 런타임에 지정 된 프로그램 엔터티에 대 한 특성 정보를 검색 하는 방법을 보여 줍니다.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"));
    }
}

리플렉션을 통해 특정 특성이 요청되면 특성 클래스에 대한 생성자가 프로그램 소스에 제공된 정보와 함께 호출되고 결과 특성 인스턴스가 반환됩니다.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. 속성을 통해 추가 정보를 제공한 경우 해당 속성은 특성 인스턴스가 반환되기 전에 지정된 값으로 설정됩니다.If additional information was provided through properties, those properties are set to the given values before the attribute instance is returned.