팁 (조언)
소프트웨어 개발이 새로운가요? 먼저 시작하기 자습서부터 시작하세요. 동작 및 상태를 사용하여 개체를 모델링해야 하면 클래스가 발생합니다.
다른 언어로 경험하신 적 있나요? C# 클래스는 Java 또는 C++의 클래스와 유사합니다. C#관련 패턴에 대한 개체 이니셜라이저 및 컬렉션 이니셜라이저 섹션을 건너 들이고 데이터 중심 대안에 대한 레코드 를 참조하세요.
클래스는 개체의 청사진을 정의하는 참조 형식입니다. 클래스 형식의 변수를 만들 때 변수는 관리되는 힙의 개체에 대한 참조 를 보유합니다. 변수는 개체 데이터 자체를 보유하지 않습니다. 클래스 변수를 다른 변수에 할당하면 참조가 복사되므로 두 변수 모두 동일한 개체를 가리킵니다. 클래스는 C#에서 사용자 지정 형식을 정의하는 가장 일반적인 방법입니다. 참조 간에 복잡한 동작, 상속 또는 공유 ID가 필요한 경우 사용합니다.
클래스 선언
키워드와 형식 이름을 사용하여 클래스 class 를 정의합니다. 선택적 액세스 한정자는 표시 유형을 제어합니다. 기본값은 다음과 같습니다.internal
public class Customer
{
public string Name { get; set; }
public Customer(string name) => Name = name;
}
클래스 본문에는 필드, 속성, 메서드 및 이벤트가 포함되며, 클래스 멤버라고도 합니다. 이름은 유효한 C# 식별자 이름이어야 합니다.
개체 만들기
클래스는 형식을 정의하지만 개체 자체는 아닙니다. 키워드를 사용하여 개체(클래스의 인스턴스 )를 만듭니다 new .
var customer = new Customer("Allison");
Console.WriteLine(customer.Name); // Allison
변수 customer 는 개체 자체가 아니라 개체에 대한 참조를 보유합니다. 동일한 개체에 여러 변수를 할당할 수 있습니다. 한 참조를 통한 변경 내용은 다른 참조를 통해 표시됩니다.
var c1 = new Customer("Grace");
var c2 = c1; // both variables reference the same object
c2.Name = "Hopper";
Console.WriteLine(c1.Name); // Hopper — c1 sees the change made through c2
이 참조 공유 동작은 할당이 데이터를 복사하는 클래스와 구조체 간의 한 가지 차이점입니다. 더 중요한 것은 클래스가 상속을 지원합니다. 파생 형식이 다시 사용되고 기본 클래스의 동작을 특수하게 지정하는 계층 구조를 빌드할 수 있습니다. 구조체는 상속 계층 구조에 참여할 수 없습니다. 차이점에 대한 자세한 내용은 값 형식 및 참조 형식을 참조하세요.
생성자 및 초기화
인스턴스를 만들 때 해당 필드와 속성을 유용한 값으로 초기화하려고 합니다. C#에서는 필드 이니셜라이저, 생성자 매개 변수, 기본 생성자 및 필수 속성과 같은 여러 가지 방법을 제공합니다.
필드 이니셜라이저는 필드 선언에서 직접 기본값을 설정합니다.
public class Container
{
private int _capacity = 10;
}
필드 이니셜라이저는 내부 기본값을 정의합니다. 호출자에게 초기 값을 선택할 수 있는 방법을 제공하지 않습니다. 클래스의 소비자가 값을 제공할 수 있도록 하려면 다음 기술 중 하나를 사용합니다.
생성자 매개 변수 를 사용하려면 호출자가 다음 값을 제공해야 합니다.
public class Container
{
private int _capacity;
public Container(int capacity) => _capacity = capacity;
}
기본 생성자 (C# 12 이상)는 클래스 선언에 직접 매개 변수를 추가합니다. 이러한 매개 변수는 클래스 본문 전체에서 사용할 수 있습니다.
public class Container(int capacity)
{
private int _capacity = capacity;
}
기본 생성자와 필드 이니셜라이저가 함께 작동할 수 있습니다. 필드 이니셜라이저 _capacity = capacity 는 기본 생성자 매개 변수를 해당 값으로 사용합니다. 이 패턴을 사용하면 단일 간결한 선언을 사용하여 필드에서 생성자 인수를 캡처할 수 있습니다.
필수 속성 은 호출자가 개체 이니셜라이저를 통해 특정 속성을 설정하도록 적용합니다.
public class Person
{
public required string FirstName { get; set; }
public required string LastName { get; set; }
}
// var missing = new Person(); // Error: required properties not set
var person = new Person { FirstName = "Grace", LastName = "Hopper" };
Console.WriteLine($"{person.FirstName} {person.LastName}"); // Grace Hopper
매개 변수 유효성 검사 및 생성자 체인을 비롯한 생성자 패턴을 자세히 알아보려면 생성자를 참조하세요.
정적 클래스
클래스는 static 인스턴스화할 수 없으며 정적 멤버만 포함합니다. 정적 클래스를 사용하여 인스턴스 데이터에서 작동하지 않는 유틸리티 메서드를 구성합니다.
static class MathHelpers
{
public static double CircleCircumference(double radius) =>
2 * Math.PI * radius;
}
double circumference = MathHelpers.CircleCircumference(5.0);
Console.WriteLine($"Circumference: {circumference:F2}"); // Circumference: 31.42
.NET 클래스 라이브러리에는 다음과 같은 MathConsole많은 정적 클래스가 포함됩니다. 정적 클래스는 암시적으로 봉인됩니다. 파생하거나 인스턴스화할 수 없습니다.
개체 초기화자
개체 이니셜라이저를 사용하면 값의 모든 조합에 대한 생성자를 작성하지 않고도 개체를 만들 때 속성을 설정할 수 있습니다.
class ConnectionOptions
{
public string Host { get; init; } = "localhost";
public int Port { get; init; } = 80;
public bool UseSsl { get; init; }
}
var options = new ConnectionOptions
{
Host = "db.example.com",
Port = 5432,
UseSsl = true
};
Console.WriteLine($"{options.Host}:{options.Port} (SSL: {options.UseSsl})");
// db.example.com:5432 (SSL: True)
개체 이니셜라이저는 set 또는 init 접근자가 있는 모든 엑세스 가능한 속성에서 작동합니다. 호출자가 다른 매개 변수를 required 설정하도록 하면서 속성 및 일부 매개 변수를 허용하는 생성자와 자연스럽게 결합합니다.
컬렉션 이니셜라이저
컬렉션은 목록, 집합, 사전, 배열 및 범위와 같은 관련 값 그룹을 포함하는 형식입니다. .NET 클래스 라이브러리는 배열과 List<T>함께 , Dictionary<TKey,TValue>및 와 HashSet<T>같은 Span<T>범용 컬렉션 형식을 제공합니다.
컬렉션 식 (C# 12 이상)을 사용하면 대괄호 구문을 사용하여 컬렉션을 만들 때 컬렉션을 인라인으로 채울 수 있습니다.
List<string> languages = ["C#", "F#", "Visual Basic"];
// The spread operator (..) composes collections from existing sequences:
List<string> moreLangs = [.. languages, "Python", "TypeScript"];
Console.WriteLine(string.Join(", ", moreLangs));
// C#, F#, Visual Basic, Python, TypeScript
컬렉션 식은 배열, List<T>Span<T>및 컬렉션 초기화를 지원하는 모든 형식에서 작동합니다. 스프레드 연산자(..)는 피연산자의 모든 요소를 새 컬렉션에 추가합니다. 피연산자는 전체 컬렉션일 필요는 없으며 하위 범위, LINQ 쿼리 또는 필터링된 하위 집합과 같은 시퀀스를 생성하는 식일 수 있습니다. 자세한 내용은 컬렉션 식(C# 참조)을 참조하세요.
상속
클래스는 상속을 지원합니다. 기존 클래스의 동작을 재사용, 확장 또는 수정하는 새 클래스를 정의할 수 있습니다. 상속하는 클래스는 기본 클래스이고 새 클래스는 파생 클래스입니다.
var manager = new Manager("Satya", "Engineering");
Console.WriteLine($"{manager.Name} manages {manager.Department}");
// Satya manages Engineering
클래스는 하나의 기본 클래스에서 상속하고 여러 인터페이스를 구현할 수 있습니다. 파생 클래스는 생성자를 제외한 기본 클래스의 모든 멤버를 상속합니다. 자세한 내용은 상속 및 인터페이스를 참조하세요.
클래스를 사용하는 경우
다음과 같은 경우 클래스를 사용합니다.
- 형식은 복잡한 동작을 가지거나 변경 가능한 상태를 관리합니다.
- 파생 특수화를 사용하여 기본 클래스를 만들거나 기존 클래스를 확장하는 파생 형식을 만들려면 상속이 필요합니다.
- 인스턴스는 데이터 번들뿐만 아니라 공유 ID를 나타냅니다(동일한 개체에 대한 두 개의 참조는 동기화 상태를 유지해야 합니다).
- 형식은 크거나 수명이 길며 힙 할당 및 참조 의미 체계의 이점을 누릴 수 있습니다.
참고하십시오
.NET