접기
internal 키워드는 형식 및 형식 멤버에 대한 액세스 한정자입니다.
using System;
class Program {
static void Main(string[] args)
{
Test();
}
static void Test()
{
CallStackLog();
}
static void CallStackLog()
{
var st = new System.Diagnostics.StackTrace(true);
string callstack = "";
foreach (var frame in st.GetFrames()) {
callstack += string.Format($"파일명:{0}, 라인:{1}, 함수명:{2}\n",
frame.GetFileName(),
frame.GetFileLineNumber(),
frame.GetMethod());
}
Console.WriteLine(callstack);
}
}
같은 어셈블리에서 접근 가능함.
참고자료
https://docs.microsoft.com/ko-kr/dotnet/csharp/language-reference/keywords/sealed
https://docs.microsoft.com/ko-kr/dotnet/csharp/language-reference/keywords/internal
접기 접기
readonly 키워드는 세 가지 컨텍스트에서 사용할 수 있는 한정자입니다.
필드 선언에서 필드에 대한 할당을 나타내는 readonly는 선언의 일부로 또는 동일한 클래스의 생성자에서만 발생할 수 있습니다. readonly struct 정의에서 readonly는 struct가 불변임을 나타냅니다. ref readonly 메서드 반환에서 readonly 한정자는 해당 메서드가 참조를 반환하고 해당 참조에 쓰기를 허용하지 않음을 나타냅니다. class Age {
readonly int year;
Age(int year)
{
this.year = year;
}
void ChangeYear()
{
//year = 1967; // Compile error if uncommented.
}
}
참고자료
접기 접기
클래스에 적용된 경우 sealed 한정자는 다른 클래스가 해당 클래스에서 상속하지 못하도록 합니다.
다음 예제에서 B 클래스는 A 클래스에서 상속하지만 B 클래스에서 상속할 수 있는 클래스는 없습니다.
class Vector2 {
public int X;
public int Y;
}
sealed class SealedClass : Vector2 {
int Index;
}
class SealedTest : SealedClass {
// 파생 불가 컴파일 에러
}
static void Main()
{
SealedClass sc = new SealedClass() {
X = 110,
Y = 150,
};
Console.WriteLine($"x = {sc.X}, y = {sc.Y}");
}
클래스에서 새 메서드 또는 속성을 정의할 때 virtual로 선언하지 않으면 파생 클래스가 재정의하지 못하도록 할 수 있습니다.
추상 클래스는 추상 메서드 또는 속성 구현을 제공하는 클래스에 상속되어야 하므로 봉인 클래스에 abstract 한정자를 사용하면 오류가 발생합니다.
메서드 또는 속성에 적용된 경우 sealed 한정자는 항상 override와 함께 사용해야 합니다.
참고자료
https://docs.microsoft.com/ko-kr/dotnet/csharp/language-reference/keywords/sealed
접기 접기
volatile 키워드는 동시에 실행되는 여러 스레드에 의해 필드가 수정될 수 있음을 나타냅니다.
volatile 로 선언된 필드에는 단일 스레드에 의한 액세스를 가정하는 컴파일러 최적화가 적용되지 않음.
volatile 를 사용하는 형식
참조 형식
포인터 형식
sbyte, byte, short, ushory, int uint, char, float, bool 등의 형식
참조 형식으로 알려진 제네릭 형식 매개변수
Volatile 키워드는 클래스 또는 구조체의 필드에만 적용할 수 있습니다.
지역 변수는 volatile로 선언할 수 없습니다.
예제
using System;
using System.Threading;
public class Worker {
// 스레드로 호출
public void DoWork()
{
while (!_shouldStop) {
Console.WriteLine("Worker thread: working...");
}
Console.WriteLine("Worker thread: terminating gracefully.");
}
public void RequestStop()
{
_shouldStop = true;
}
// volatile이라는 키워드는 컴파일러에게이 데이터에 대한 힌트로 사용됩니다.
// member는 여러 스레드에 의해 액세스됩니다.
private volatile bool _shouldStop;
}
public class WorkerThreadExample {
static void Main()
{
// 작업자 스레드 객체를 만듭니다. 이것은 스레드를 시작하지 않습니다.
Worker workerObject = new Worker();
Thread workerThread = new Thread(workerObject.DoWork);
// 작업자 스레드를 시작합니다.
workerThread.Start();
Console.WriteLine("Main thread: starting worker thread...");
// 작업자 스레드가 활성화 될 때까지 반복하십시오.
while (!workerThread.IsAlive) ;
// 주 스레드를 1 밀리 초 동안 sleep 상태로 둡니다.
// 작업자 스레드가 어떤 작업을하도록 허용합니다.
Thread.Sleep(1);
// 작업자 스레드가 스스로를 중단하도록 요청합니다.
workerObject.RequestStop();
// Thread.Join 메서드를 사용하여 현재 스레드를 차단합니다.
// 객체의 스레드가 종료 될 때까지.
workerThread.Join();
Console.WriteLine("Main thread: worker thread has terminated.");
}
// Sample output:
// Main thread: starting worker thread...
// Worker thread: working...
// Worker thread: working...
// Worker thread: working...
// Worker thread: working...
// Worker thread: working...
// Worker thread: working...
// Worker thread: terminating gracefully.
// Main thread: worker thread has terminated.
}
실행 결과
참고자료
https://docs.microsoft.com/ko-kr/dotnet/csharp/language-reference/keywords/volatile
접기 접기
unsafe를 사용하려면 빌드 옵션에 안전하지 않은 코드 허용 옵션을 켜야한다.
프로젝트 설정 -> 빌드 -> 안전하지 않은 코드 허용 체크
프로젝트 설정 -> 빌드 -> 안전하지 않은 코드 허용 체크
// Unsafe method: takes pointer to int:
unsafe static void SquarePtrParam(int* p)
{
*p *= *p;
}
unsafe static void Main()
{
int i = 5;
// Unsafe method: uses address-of operator (&):
SquarePtrParam(&i); // 25
Console.WriteLine(i);
}
unsafe를 사용하면 C#에서 C++ 처럼 레퍼런스( &) 와 포인터( *) 사용이 가능함.
참고자료
https://docs.microsoft.com/ko-kr/dotnet/csharp/language-reference/keywords/unsafe
접기