티스토리 뷰

IT지식

c# 에서 checked, fixed, lock, params

민자르 2018. 5. 10. 14:17
반응형

1. checked / unchecked


checked는 키워드는 정수 형식 산술 연산 및 변환에 대한 오버플로 검사를 명시적으로 사용하도록 설정하는 데 사용됩니다.


int ten = 10; int i2 = 2147483647 + ten;


상수 값만 포함된 식이 대상 형식의 범위를 벗어난 값을 생성할 경우 기본적으로 이 식에서는 컴파일러 오류가 발생합니다. 식에 하나 이상의 상수가 아닌 값이 포함된 경우 컴파일러에서는 오버플로를 감지하지 않습니다. 예제에서 i2에 할당된 식을 계산하면 컴파일러 오류가 발생하지 않습니다.


기본적으로 이러한 상수가 아닌 식은 런타임에 오버플로가 있는지 검사되지 않고 오버플로 예외를 일으키지 않습니다. 이전 예제는 양의 정수 2개의 합계로 -2,147,483,639를 표시합니다.

오버플로 검사는 컴파일러 옵션, 환경 구성 또는 checked 키워드 사용을 통해 사용하도록 설정될 수 있습니다. 



// Checked expression

Console.WriteLine(checked(2147483647 + ten));


// Checked block

checked

{

int i3 = 2147483647 + ten;

Console.WriteLine(i3);

}



다음 예제에서는 checked 식 또는 checked 블록을 사용하여 런타임에 이전 합계에 의해 생성되는 오버플로를 감지하는 방법을 보여 줍니다. 두 예제는 모두 오버플로 예외를 일으킵니다.


unchecked 키워드는 정수 형식 산술 연산 및 변환에 대한 오버플로 검사를 비활성화하는 데 사용됩니다.


unchecked

{

int1 = 2147483647 + 10;

}

int1 = unchecked(ConstantMax + 10);


오버플로를 확인하는 데 시간이 걸리기 때문에 오버플로 위험이 없는 상황에서는 unchecked 코드를 사용하여 성능을 향상할 수 있습니다. 그러나 오버플로가 발생할 가능성이 있는 경우 checked 환경을 사용해야 합니다.



2. fixed


fixed 문은 가비지 수집기에서 이동 가능한 변수를 재배치할 수 없도록 합니다. fixed 문은 unsafe 컨텍스트에서만 허용됩니다. Fixed를 사용하여 고정 크기 버퍼를 만들 수도 있습니다.


fixed 문은 관리되는 변수에 대한 포인터를 설정하고 문을 실행하는 동안 해당 변수를 "고정"합니다. 이동 가능한 관리되는 변수에 대한 포인터는 fixed 컨텍스트에만 유용합니다. fixed 컨텍스트 없는 가비지 수집은 예기치 않게 변수를 재배치할 수 있습니다. C# 컴파일러만 fixed 문에서 관리되는 변수에 대한 포인터를 할당할 수 있습니다.


class Point

{

public int x;

public int y;

}


unsafe private static void ModifyFixedStorage()

{

Point pt = new Point();


fixed (int* p = &pt.x)

{

*p = 1;

}

}


3. lock


lock 키워드는 지정된 개체에 대한 상호 배타적 잠금을 얻고 문을 실행한 다음 잠금을 해제하여 문 블록을 임계 영역으로 표시합니다. 다음 예제에는 lock 문이 포함되어 있습니다.


lock 키워드는 한 스레드가 임계 영역에 있는 동안 다른 스레드가 코드의 임계 영역에 들어오지 않도록 합니다. 다른 스레드가 잠긴 코드에 들어오려고 하면 개체가 해제될 때까지 대기 및 차단됩니다.


class MyClass

{

private int counter = 1000;

// 임계영역 접근 키

private object lockObject = new object();

public void Run()

{

// 10개의 쓰레드가 동일 메서드 실행

for (int i = 0; i < 10; i++)

{

new Thread(SafeCalc).Start();

}

}

private void SafeCalc()

{

// 한번에 하나의 스레드만 키를 가지고 접근

lock (lockObject)

{

counter++;

for (int i = 0; i < counter; i++)

for (int j = 0; j < counter; j++) ;

Console.WriteLine(counter);

}

}

}


4. params


매개 변수 선언이나 지정된 형식의 인수 배열에 지정된 형식의 쉼표로 구분된 인수 목록을 보낼 수 있습니다. 인수를 보내지 않을 수도 있습니다. 인수를 보내지 않는 경우 params 목록의 길이는 0입니다.

메서드 선언에서 params 키워드 뒤에는 추가 매개 변수가 허용되지 않으며, params 키워드 하나만 메서드 선언에 사용할 수 있습니다.



public void UseParams(params int[] list)

{

for (int i = 0; i < list.Length; i++)

{

Console.Write(list[i] + " ");

}

}


public void UseParams2(params object[] list)

{

for (int i = 0; i < list.Length; i++)

{

Console.Write(list[i] + " ");

}

}


UseParams(1, 2, 3, 4);

UseParams2(1, 'a', "test");


728x90
반응형
댓글