소개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에 대 한 Microsoft의 c # 컴파일러는 이러한 두 표준의 준수 구현입니다.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. int 및 double과 같은 기본 형식을 포함하는 모든 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# 설계의 측면에는 별도의 virtual 및 override 한정자, 메서드 오버로드 확인 규칙 및 명시적 인터페이스 멤버 선언에 대한 지원이 포함됩니다.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 클래스) 및 많은 다른 네임스페이스(예: IO 및 Collections)가 포함되어 있습니다.Namespaces contain types and other namespaces—for example, the System namespace contains a number of types, such as the Console class referenced in the program, and a number of other namespaces, such as IO and Collections. 지정된 네임스페이스를 참조하는 using 지시문을 사용하여 해당 네임스페이스의 멤버인 형식을 정규화되지 않은 방식으로 사용할 수 있습니다.A using directive that references a given namespace enables unqualified use of the types that are members of that namespace. using 지시문 때문에, 프로그램은 Console.WriteLine을 System.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. Main 메서드는 static 한정자로 선언됩니다.The 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. 어셈블리는 일반적으로 .exe .dll *응용 프로그램* 을 구현 하는지, 아니면 _ *라이브러리 를 구현 하는지에 따라 파일 확장명이 또는입니다.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개의 메서드 Push 및 Pop, 중첩된 클래스 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) 명령 형식의 실행 코드와 _ metadata * 형태의 기호화 된 정보가 포함 되어 있습니다.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. 값 형식에서는 변수에 데이터의 자체 사본이 들어 있으며 한 변수의 작업이 다른 변수에 영향을 미칠 수 없습니다(ref 및 out 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.
두 부동 소수점 형식 및는 float double 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 |
-32768 ... 32, 767-32,768...32,767 | |
| 3232 | int |
-2147483648 ... 2, 147, 483, 647-2,147,483,648...2,147,483,647 | |
| 6464 | long |
-9223372036854775808 ... 9, 223, 372, 036, 854, 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[,] 는의 2 차원 배열이 int 고,은의 1 차원 배열에 해당 하는 int[][] 1 차원 int 배열입니다.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 T? 추가 값을 보유할 수 있는 해당 nullable 형식이 있습니다 null .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. 값 형식의 값은 boxing _ 및 _ unboxing 작업을 수행 하 여 개체로 처리 됩니다.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 _ z는 x + (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 |
x를 T 형식으로 명시적 변환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 |
x가 T이면 true 반환, 그렇지 않으면 false 반환Return true if x is a T, false otherwise |
|
x as T |
T로 형식이 지정된 x 반환, x가 T가 아닌 경우 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 |
가 이면 y x 이 null 고, x 그렇지 않으면로 평가 됩니다.Evaluates to y if x is null, to x otherwise |
| 조건부Conditional | x ? y : z |
x가 true이면 y, x가 false이면 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 , = 및 복합 할당 연산자를 사용 하는 할당, 및 연산자를 사용 하는 증가 및 감소 작업, 및 연산자를 사용 하는 ++ -- 식 사용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. 이 그룹에는 if 및 switch 문이 포함됩니다.In this group are the if and switch statements.
반복 문은 포함 문을 반복 해 서 실행 하는 데 사용 됩니다.Iteration statements are used to repeatedly execute an embedded statement. 이 그룹에는 while, do, for 및 foreach 문이 포함됩니다.In this group are the while, do, for, and foreach statements.
점프 문 은 제어를 전달하는 데 사용됩니다.Jump statements are used to transfer control. 이 그룹에는 break, continue, goto, throw, return 및 yield 문이 포함됩니다.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.
checked및 unchecked 문은 정수 계열 형식 산술 연산 및 변환에 대 한 오버플로 검사 컨텍스트를 제어 하는 데 사용 됩니다.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);
}
}
throw 및 try 문throw 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!");
}
}
checked 및 unchecked 문checked 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
클래스의 멤버는 *static 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.
| MemberMember | 설명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 then be used in the body of the class declarations to define the members of the class. 다음 예제에서 Pair의 형식 매개 변수는 TFirst 및 TSecond입니다.In the following example, the type parameters of Pair are TFirst and TSecond:
public class Pair<TFirst,TSecond>
{
public TFirst First;
public TSecond Second;
}
형식 매개 변수를 사용 하도록 선언 된 클래스 형식을 제네릭 클래스 형식 이라고 합니다.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. 앞의 예제에서 Point3D는 Point에서 x 및 y 필드를 상속하고 모든 Point3D 인스턴스는 세 개의 필드, 즉 x, y 및 z를 포함합니다.In the previous example, Point3D inherits the x and y fields from Point, and every Point3D instance contains three fields, x, y, and z.
클래스 형식에서 해당 기본 클래스 형식 간에 암시적 변환이 존재합니다.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, g 및 b 인스턴스 필드의 별도 복사본을 갖지만 Black, White, Red, Green 및 Blue 정적 필드의 복사본은 하나뿐입니다.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.
메서드에는 메서드에 전달 되는 값 또는 변수 참조를 나타내는 *parameters _의 목록이 비어 있을 수 있으며, 메서드에서 계산 되 고 반환 되는 값의 형식을 지정 하는 _ *반환 형식* *이 있습니다.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. System.Console 클래스의 Write 및 WriteLine 메서드는 매개 변수 배열 사용의 좋은 예입니다.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.
GetNextSerialNo 및 SetNextSerialNo 정적 메서드는 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"
}
}
SetNextSerialNo 및 GetNextSerialNo 정적 메서드는 클래스에 대해 호출되지만 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, VariableReference 및 Operation을 선언합니다.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.
Evaluate의 Constant 구현은 단순히 저장된 상수를 반환합니다.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 클래스를 사용하여 x 및 y의 다른 값에 대해 식 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.
다음 코드에서는 List<T> 개체의 growable 목록을 구현 하는 라는 제네릭 클래스를 보여 줍니다.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. *Instance 생성자 는 클래스의 인스턴스를 초기화 하는 데 필요한 작업을 구현 하는 멤버입니다.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<string> 클래스의 각 생성자를 사용 하 여 두 개의 인스턴스를 할당 합니다 List .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 set 읽기/쓰기 속성 입니다. 접근자만 있는 속성은 get _읽기 전용 속성*_ 이며 접근자만 있는 속성은 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> 클래스는 각각 읽기 전용 및 읽기/쓰기 특성을 갖는 두 개의 속성 Count 및 Capacity를 선언합니다.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 접근자와 비슷한 add 및 remove 접근자를 명시적으로 제공할 수 있습니다.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. 모든 연산자는 public 및 static으로 선언해야 합니다.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. 특히, 이러한 연산자는 해당 Equals 메서드를 사용하여 포함된 각 개체를 비교할 때 두 List<T> 인스턴스의 같음을 정의합니다.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.WriteLine은 True를 출력합니다.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==이 정의되지 않았으면 a 및 b은 다른 List<int> 인스턴스를 참조하므로 첫 번째 Console.WriteLine은 False를 출력합니다.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 와가 a b 같은 개체를 참조 하기 때문입니다.If Point is a class, the output is 20 because a and b reference the same object. 가 struct 인 경우는 Point 에 대 한 10 할당이 a 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. 둘째, ref 및 out 매개 변수를 제외하고, 구조체에 대한 참조를 만들 수 없으므로 다양한 상황에서 사용하는 것이 불가능합니다.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
*Array _은 계산 된 인덱스를 통해 액세스 되는 여러 변수를 포함 하는 데이터 구조입니다.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#에서는 다차원 배열도 지원합니다.C# also supports multi-dimensional arrays. 배열 형식의 _ rank* 라고도 하는 배열 형식의 차원 수는 배열 형식의 대괄호 사이에 쓰여진 쉼표 수를 더한 값입니다.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. 다음 예제에서 인터페이스 IComboBox는 ITextBox 및 IListBox를 둘 다 상속합니다.In the following example, the interface IComboBox inherits from both ITextBox and IListBox.
interface IControl
{
void Paint();
}
interface ITextBox: IControl
{
void SetText(string text);
}
interface IListBox: IControl
{
void SetItems(string[] items);
}
interface IComboBox: ITextBox, IListBox {}
클래스 및 구조체는 여러 인터페이스를 구현할 수 있습니다.Classes and structs can implement multiple interfaces. 다음 예제에서 클래스 EditBox는 IControl 및 IDataBound를 둘 다 구현합니다.In the following example, the class EditBox implements both IControl and IDataBound.
interface IDataBound
{
void Bind(Binder b);
}
public class EditBox: IControl, IDataBound
{
public void Paint() {...}
public void Bind(Binder b) {...}
}
클래스 또는 구조체가 특정 인터페이스를 구현하는 경우 해당 클래스 또는 구조체의 인스턴스를 해당 인터페이스 형식으로 암시적으로 변환할 수 있습니다.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. 예를 들어 다음 문은 동적 형식 캐스팅을 사용 하 여 개체의 IControl 및 IDataBound 인터페이스 구현을 가져옵니다.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 Paint 메서드와 IControl 인터페이스의 메서드는 멤버를 Bind IDataBound 사용 하 여 구현 됩니다 public .In 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.Paint 및 IDataBound.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 먼저 EditBox 인터페이스 형식에 대 한 참조를 변환 하는 경우에만 호출할 수 있습니다 IControl .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 Red Green 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 메서드는 double[]의 요소에 지정된 Function을 적용하여 결과가 있는 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, internal 및 private 한정자를 사용하여 제어됩니다.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 Display 클래스의 메서드에 연결 합니다.This 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.