
정적 클래스는 new 키워드를 사용해서 인스턴스 만들기 불가능
class 키워드 앞에static키워드를 선언해서 사용
정적 클래스의 모든 멤버는static으로 선언
객체들이 처음 호출될 때 생성되고 종료될 때 해체되기 때문에 정적 클래스는 어디서든 접근 가능
전역적으로 접근해야 하는 유틸리티 클래스를 만들 때 정적 클래스로 만들면 유용하게 사용가능
생성자를 가질 수 없음 == static class는 객체를 생성할 수 없기 때문
static 생성자를 이용할때는? 주로 static 필드들을 초기화 할때 사용
생성자가 실행되는 시점은?
① 클래스의 정적필드에 접근하기 직전에 호출
② 클래스의 인스턴스를 생성하기 직전에 호출
③ 모든 클래스의 정적 생성자는 최초 한번만 호출
인스턴스란
어떤 원본(추상적인 개념)으로부터 '생성된 복제본'을 의미
// static 클래스 정의
public static class MyUtility
{
private static int ver;
// static 생성자
static MyUtility()
{
ver = 1;
}
public static string Convert(int i)
{
return i.ToString();
}
public static int ConvertBack(string s)
{
return int.Parse(s);
}
}
// static 클래스 사용
static void Main(string[] args)
{
string str = MyUtility.Convert(123);
int i = MyUtility.ConvertBack(str);
}
정적 메소드는 인스턴스를 직접 생성하지않고 호출 가능
static키워드를 선언해서 사용
메소드 내부에서 객체의 멤버를 참조할수 없음
인스턴스에서는 호출 할 수 없음
public class MyClass
{
private int val = 1;
// 인스턴스 메서드
public int InstRun()
{
return val;
}
// 정적(Static) 메서드
public static int Run()
{
return 1;
}
}
public class Client
{
public void Test()
{
// 인스턴스 메서드 호출
MyClass myClass = new MyClass();
int i = myClass.InstRun();
// 정적 메서드 호출
int j = MyClass.Run();
}
}
인스턴스를 직접 생성하지않고 접근 가능
자료형 앞에static키워드를 선언해서 사용
어디서든지 접근 가능할 수 있기 때문에 주로 전역적으로 접근해야하는 변수의 경우일때 사용
클래스 내의 Non-static 필드들은 클래스 인스턴스를 생성할 때마다 메모리에 매번 새로 생성하게 되는 반면,static필드는 프로그램 실행 후 해당 클래스가 처음으로 사용될 때 한번 초기화되어 계속 동일한 메모리를 사용
public class Book
{
public static int count = 0;
private string name;
public Book (string name)
{
this.name = name;
count++;
}
}
public class Program
{
static void Main (string[] args)
{
Book book1 = new Book ("Harry Potter");
Book book2 = new Book ("The Lord of the Rings");
Console.WriteLine ("Created Book Count : " + Book.count);
}
}
// static 필드
protected static int _id;
// static 속성
public static string Name { get; set; }
싱글톤 패턴
인스턴스가 하나만 생성되도록 보장하는 디자인 패턴 중 하나
정적 생성자를 사용하여 구현할 때 정적 멤버 변수를 초기화하고 유일한 인스턴스를 생성
① 정적 멤버를 간단히 초기화 하는 경우
'instance'라는 정적 멤버 변수는 클래스가 처음으로 사용될 때 한번만 초기화 되고 유지
public class MySingleton
{
// 정적 멤버 변수 선언 및 초기화
private static readonly MySingleton instance = new MySingleton();
// 정적 프로퍼티
public static MySingleton Instance { get { return instance; } }
// private 생성자
private MySingleton()
{
// 외부에서 직접 인스턴스 생성 방지
}
}
② 정적 생성자을 활용하여 초기화 하는 경우
정적 생성자를 활용하여 초기화과정을 더 복잡하게 처리 가능
클래스가 처음으로 사용될 때 호출되며 해당 호출 이전에 정적 멤버 변수인 'instance'를 초기화
public class MySingleton
{
// 정적 멤버 변수 선언
private static readonly MySingleton instance;
//정적 생성자
static MySingleton()
{
// 정적 멤버 변수 초기화
instance = new MySingleton();
}
// 정적 프로퍼티
// example이 호출될때 instance가 반환
public static MySingleton example { get { return instance; } }
// private 생성자
private MySingleton()
{
// 외부에서 직접 인스턴스 생성 방지
}
}
③ 반드시 정적 생성자를 사용해야 하는 경우 : 예외가 발생할 가능성이 있는 경우
멤버 초기화 구문 대신 반드시 정적 생성자를 사용해야 하는 경우
바로 예외가 발생할 가능성이 있는 경우!
(멤버 초기화 구문의 경우에는 예외를 잡을 방법이 없음)
//정적 생성자
static MySingleton()
{
try
{
instance = new MySingleton();
}
catch
{
// 복구를 시도한다
}
}
static이란?
하나의 객체에 종속되는 것이 아닌 클래스 자체에 속하는 문법
그렇기때문에 static으로 선언된 변수는 객체가 아무리 많더라도 클래스당 1개밖에 가지지 못함
객체가 생성되지 않아도 클래스의 이름을 통해 접근이 가능
모든 객체가 하나의 변수를 공유해야 하는 상황에서 많이 쓰임
유틸리티 클래스를 만들 때 어디서든 쉽게 사용하고 싶을 때 사용
Utility class(유틸리티 클래스)
각각의 클래스들을 정적으로 하나하나씩 작성하는 것이 아니라, 하나의 코드로 여러 클래스들을 동적으로 생성하는 방식
const란?
상수를 정의하는데 사용하는 문법
const를 사용할 경우 컴파일러는 상수로 판단하기 때문에 값 변경이 없는 수라고 판단하여 성능 향상
상수: 한번 값이 설정되면 변경할 수 없는 것
언제 사용되는지?
① 매직 넘버 대체 사용 : 매직 넘버는 그 자체로 의미나 용도를 명확하게 표현하지 않는 숫자를 의미
② 프로그램에서 여러번 사용되는 값 대체
const를 사용할 수 있는 조건
① 기본 자료형
int, float, double, bool, char, string 등 기본 자료형을 상수로 선언 가능
② 컴파일 타임에 결정되는 값 : 상수로 선언된 값은 컴파일 타임에 결정되어야 함, 즉 상수식(constant expression)이어야 함
const를 사용할 수 없는 조건
① 런타임에 결정되는 값 : 런타임에 계산되거나 결정되는 값은 const로 선언 불가능
② 참조 타입 : 참조 타입 객체의 인스턴스는 const로 선언 불가능, 대신 readonly 사용
③ 복잡한 계산 또는 함수 호출 결과 : 컴파일 타임에 계산되지 않는 복잡한 수식이나 함수 호출 결과는 const 사용 불가능
stack 단, static 선언을 하면 heap에 저장 가능heapconst는 stack 메모리에 저장되기 때문에 접근이 빠르다는 장점이 있지만, const는 컴파일 상수이기 때문에 const 값이 바뀌는 경우 해당 프로젝트 뿐만 아니라 참조 받거나 영향 받는 프로젝트 모두 재 컴파일을 해야하는 단점이 있음
반면, readonly는 생성시 선언하지 않아도 생성자에서 초기화하여 사용할 수 있기 때문에 유연하고, 실제 사용하는 단계에서 변수의 값을 가져오는 장점이 존재
상수값 변경 시 재 컴파일을 하지 않고 사용하는 생성자에서 변수에 값을 할당하여 사용할 수 있기 때문에 const보다는 readonly 사용이 good
객체 지향 프로그래밍에서 클래스 수준의 데이터 관리와 메소드 호출에 유용하게 사용됩니다. 객체 간 데이터 공유, 메모리 사용 최적화, 코드 구조화 등 다양한 장점을 제공