C# 키워드 T~Z 프로그래밍/C#2016. 6. 3. 19:48
this
1. this 키워드는 클래스의 현재 인스턴스를 가리키며 확장 메서드의 첫째 매개 변수에 대한 한정자로도 사용됩니다.
![]() |
---|
이 문서에서는 this를 클래스 인스턴스와 함게 사용하는 방법을 설명합니다. 확장 메서드에서 이를 사용하는 방법에 대한 자세한 내용은 확장 메서드(C# 프로그래밍 가이드)를 참조하십시오. |
2. 일반적으로 this 키워드는 다음과 같이 사용됩니다.
1) 예를 들어, 비슷한 이름으로 숨겨진 멤버를 한정하는 방법은 다음과 같습니다.
public Employee(string name, string alias) { // Use this to qualify the fields, name and alias: this.name = name; this.alias = alias; }
3. 개체를 다른 메서드의 매개 변수로 전달하는 방법은 다음과 같습니다.
CalcTax(this);
4. 인덱서를 선언하는 방법은 다음과 같습니다.
public int this[int param] { get { return array[param]; } set { array[param] = value; } }
5. 클래스 수준에서 작성되고 개체의 일부로 포함되지 않는 정적 멤버 함수에는 this 포인터가 없습니다.
6. 정적 메서드에서 this를 참조하려고 하면 오류가 발생합니다.
7. 이 예제에서 this는 비슷한 이름으로 숨겨진 Employee 클래스 멤버(name, alias)를 한정(qualify)하는 데 사용됩니다.
8. 또한 다른 클래스에 속한 CalcTax 메서드로 개체를 전달하는 데 사용됩니다.
class Employee { private string name; private string alias; private decimal salary = 3000.00m; // Constructor: public Employee(string name, string alias) { // Use this to qualify the fields, name and alias: this.name = name; this.alias = alias; } // Printing method: public void printEmployee() { Console.WriteLine("Name: {0}\nAlias: {1}", name, alias); // Passing the object to the CalcTax method by using this: Console.WriteLine("Taxes: {0:C}", Tax.CalcTax(this)); } public decimal Salary { get { return salary; } } } class Tax { public static decimal CalcTax(Employee E) { return 0.08m * E.Salary; } } class MainClass { static void Main() { // Create objects: Employee E1 = new Employee("Mingda Pan", "mpan"); // Display results: E1.printEmployee(); } } /* Output: Name: Mingda Pan Alias: mpan Taxes: $240.00 */
throw
1. throw 문은 프로그램 실행 중에 비정상적인(anomalous) 상황(예외)이 발생한 경우 이를 알리는 데(signal) 사용됩니다.
2. 아래 예제에서 볼 수 있는 것처럼 throw된 예제는 System.Exception에서 바생된 클래스의 개체입니다.
class MyException : System.Exception {} // ... throw new MyException();
3. 일반적으로 throw 문은 try-catch 또는 try-finally 문과 함께 사용됩니다.
4. throw 문을 catch 블록에 사용하여 catch 블록에서 catch한 예외를 다시 throw할 수 있습니다.
5. 이 경우에 throw 문은 예외 피연산자를 사용하지 않습니다.
6. 자세한 내용 및 예제를 보려면 try-catch 및 방법: 명시적으로 예외 Throw를 참조하십시오.
7. 아래 예제는 throw 문을 사용하여 예외를 throw하는 방법을 보여줍니다.
public class ThrowTest2 { static int GetNumber(int index) { int[] nums = { 300, 600, 900 }; if (index > nums.Length) { throw new IndexOutOfRangeException(); } return nums[index]; } static void Main() { int result = GetNumber(3); } } /* Output: The System.IndexOutOfRangeException exception occurs. */
8. try-catch 및 방법: 명시적으로 예외 Throw에서 예제를 참조하십시오.
true 연산자
1. 피연산자가 true임을 나타낼 경우 bool 값 true를 반환하고, 그렇지 않을 경우 false를 반환합니다.
2. C# 2.0 이전 버전에서는 true 및 false 연산자를 사용해서 SqlBool과 같은 형식과 호환되는 사용자 정의 null 허용 값 형식을 만들었습니다.
3. 그러나 이 버전에서는 null 허용 값 형식에 대한 지원이 기본적으로 제공되므로 가능하면 true 및 false 연산자를 오버로드하는 대신 null 허용 값 형식을 사용해야 합니다.
4. 자세한 내용은 nullable 형식을 참조하십시오.
5. nullable 부을을 사용하면 a != b 식은 두 값 중 하나 이상이 null일 수 있으므로 !(a == b)과 반드시 일치하지 않습니다(is not necessarily equal to).
6. 식의 null 값을 올바르게 식별하려면 true 및 false 연산자를 개별적으로 오버로드해야 합니다
7. 다음 예제에서는 true 및 false 연산자를 오버로드하여 사용하는 방법을 보여 줍니다.
// For example purposes only. Use the built-in nullable bool
// type (bool?) whenever possible. public struct DBBool { // The three possible DBBool values. public static readonly DBBool Null = new DBBool(0); public static readonly DBBool False = new DBBool(-1); public static readonly DBBool True = new DBBool(1); // Private field that stores –1, 0, 1 for False, Null, True. sbyte value; // Private instance constructor. The value parameter must be –1, 0, or 1. DBBool(int value) { this.value = (sbyte)value; } // Properties to examine the value of a DBBool. Return true if this // DBBool has the given value, false otherwise. public bool IsNull { get { return value == 0; } } public bool IsFalse { get { return value < 0; } } public bool IsTrue { get { return value > 0; } } // Implicit conversion from bool to DBBool. Maps true to DBBool.True and // false to DBBool.False. public static implicit operator DBBool(bool x) { return x ? True : False; } // Explicit conversion from DBBool to bool. Throws an exception if the // given DBBool is Null; otherwise returns true or false. public static explicit operator bool(DBBool x) { if (x.value == 0) throw new InvalidOperationException(); return x.value > 0; } // Equality operator. Returns Null if either operand is Null; otherwise // returns True or False. public static DBBool operator ==(DBBool x, DBBool y) { if (x.value == 0 || y.value == 0) return Null; return x.value == y.value ? True : False; } // Inequality operator. Returns Null if either operand is Null; otherwise // returns True or False. public static DBBool operator !=(DBBool x, DBBool y) { if (x.value == 0 || y.value == 0) return Null; return x.value != y.value ? True : False; } // Logical negation operator. Returns True if the operand is False, Null // if the operand is Null, or False if the operand is True. public static DBBool operator !(DBBool x) { return new DBBool(-x.value); } // Logical AND operator. Returns False if either operand is False, // Null if either operand is Null, otherwise True. public static DBBool operator &(DBBool x, DBBool y) { return new DBBool(x.value < y.value ? x.value : y.value); } // Logical OR operator. Returns True if either operand is True, // Null if either operand is Null, otherwise False. public static DBBool operator |(DBBool x, DBBool y) { return new DBBool(x.value > y.value ? x.value : y.value); } // Definitely true operator. Returns true if the operand is True, false // otherwise. public static bool operator true(DBBool x) { return x.value > 0; } // Definitely false operator. Returns true if the operand is False, false // otherwise. public static bool operator false(DBBool x) { return x.value < 0; } public override bool Equals(object obj) { if (!(obj is DBBool)) return false; return value == ((DBBool)obj).value; } public override int GetHashCode() { return value; } public override string ToString() { if (value > 0) return "DBBool.True"; if (value < 0) return "DBBool.False"; return "DBBool.Null"; } }
8. true 및 false 연산자를 오버로드하는 형식은 if, do, while, for 문과 조건식에서 제어식(the controlling expression)에 사용할 수 있습니다.
9. true 연산자를 정의하는 형식은 false 연산자도 정의해야 합니다.
10. 한 형식으로 조건부 논리 연산자(&& 및 ||)를 직접 오버로드할 수 없지만, 일반적인 논리 연산자와 true 및 false 연산자를 오버로드하면 조건부 논리 연산자(the conditional logical operators)를 오버로드한 것과 같은 결과(an equivalent effect)를 얻을 수 있습니다.
true 리터럴
1. 부울(Boolean) 값 true를 나타냅니다.
class TrueTest { static void Main() { bool a = true; Console.WriteLine( a ? "yes" : "no" ); } } /* Output: yes */
try
1. catch 참조
typeof
1. 형식에 대한 System.Type 개체를 얻는 데 사용됩니다.
2. typeof 식의 형식은 다음과 같습니다.
System.Type type = typeof(int);
3. 식의 런타임 형식을 얻으려면 다음 예제와 같이 .NET Framework 메서드 GetType을 사용합니다.
int i = 0; System.Type type = i.GetType();
4. typeof 연산자는 오버로드되지 않습니다.
5. typeof 연산자는 열린 제네릭 형식에도 사용할 수 있습니다.
6. 형식 매개 변수가 둘 이상인 형식을 지정할 때는 적절한(appropriate) 수의 쉼표를 사용해야 합니다.
7. 다음 예제에서는 메서드의 반환 형식이 제네릭 IEnumerable<T>인지 여부를 확인하는 방법을 보여 줍니다
8. 메서드는 MethodInfo 형식의 인스턴스라고 가정(assume)합니다.
string s = method.ReturnType.GetInterface (typeof(System.Collections.Generic.IEnumerable<>).FullName);
public class ExampleClass { public int sampleMember; public void SampleMethod() {} static void Main() { Type t = typeof(ExampleClass); // Alternatively, you could use // ExampleClass obj = new ExampleClass(); // Type t = obj.GetType(); Console.WriteLine("Methods:"); System.Reflection.MethodInfo[] methodInfo = t.GetMethods(); foreach (System.Reflection.MethodInfo mInfo in methodInfo) Console.WriteLine(mInfo.ToString()); Console.WriteLine("Members:"); System.Reflection.MemberInfo[] memberInfo = t.GetMembers(); foreach (System.Reflection.MemberInfo mInfo in memberInfo) Console.WriteLine(mInfo.ToString()); } } /* Output: Methods: Void SampleMethod() System.String ToString() Boolean Equals(System.Object) Int32 GetHashCode() System.Type GetType() Members: Void SampleMethod() System.String ToString() Boolean Equals(System.Object) Int32 GetHashCode() System.Type GetType() Void .ctor() Int32 sampleMember */
9. 이 샘플에서는 숫자 계산의 결과를 포함하는 데 사용되는 형식을 확인하기 위해 GetType 메서드를 사용합니다.
10. 이 형식은 계산 결과(the resulting number)를 저장하는 데 필요한 요구 사항(requirements)에 따라 달라집니다.
class GetTypeTest { static void Main() { int radius = 3; Console.WriteLine("Area = {0}", radius * radius * Math.PI); Console.WriteLine("The type is {0}", (radius * radius * Math.PI).GetType() ); } } /* Output: Area = 28.2743338823081 The type is System.Double */
uint
1. uint 키워드는 다음 표에 표시된 크기와 범위에 따라 값을 저장하는 정수 계열 형식을 나타냅니다.
형식 |
범위 |
크기 |
.NET Framework 형식 |
---|---|---|---|
uint |
0 ~ 4,294,967,295 |
부호 없는 32비트 정수 |
2. uint 형식은 CLS 규격(compliant)이 아닙니다.
3. 가능하면 int를 사용합니다(use int whenever possible).
4. 다음 예제에서와 같이 uint 형식 변수를 선언하고 초기화할 수 있습니다.
uint myUint = 4294967290;
5. 정수 리터럴에 접미사가 없는 경우 해당 정수 리터럴의 형식은 그 값이 표현될 수 있는 형식인 int, uint, long, ulong 중에서 첫째 형식입니다.
6. 이 예제에서 리터럴 형식은 uint입니다.
uint uInt1 = 123;
7. 또한 다음과 같이 u 또는 U 접미사를 사용할 수 있습니다.
uint uInt2 = 123U;
8. U 또는 u 접미사를 사용하는 경우 리터럴의 형식은 리터럴의 숫자 값에 따라 uint 또는 ulong으로 결정됩니다.
Console.WriteLine(44U.GetType()); Console.WriteLine(323442434344U.GetType());
9. 이 코드는 System.UInt32 뒤에 System.UInt64(followed by)를 표시합니다.
10. 이 두 형식은 각각(respectively) uint 및 ulong의 내부 형식(the underlying types)입니다.
11. 두 번째 리터럴이 너무 커서 uint 형식으로 저장할 수 없기 때문입니다.
12. uint에서 long, ulong, float, double, decimal로의 미리 정의된 암시적 변환이 있습니다.
float myFloat = 4294967290; // OK: implicit conversion to float
13. byte, ushort, char에서 uint으로의 미리 정의된 암시적 변환이 있습니다.
14. 그 외의 다른 경우에는 캐스트를 사용해야 합니다.
15. 예를 들어 캐스트를 사용하지 않으면 다음 대입문에서 컴파일 오류가 발생합니다.
long aLong = 22; // Error -- no implicit conversion from long: uint uInt1 = aLong; // OK -- explicit conversion: uint uInt2 = (uint)aLong;
16. 또한 부동 소수점 형식에서 uint로의 암시적 변환은 없습니다.
17. 예를 들어, 다음 문에서 명시적 캐스트를 사용하지 않으면 컴파일러 오류가 발생합니다.
// Error -- no implicit conversion from double: uint x = 3.0; // OK -- explicit conversion: uint y = (uint)3.0;
18. 부동 소수점 형식 및 정수 계열 형식이 함께 사용되는 산술식에 대한 자세한 내용은 float 및 double을 참조하십시오.
19. 암시적 숫자 변환 규칙에 대한 자세한 내용은 암시적 숫자 변환 표를 참조하십시오.
ulong
1. ulong 키워드는 다음 표에 표시된 크기와 범위에 따라 값을 저장하는 정수 계열 형식을 나타냅니다.
형식 |
범위 |
크기 |
.NET Framework 형식 |
---|---|---|---|
ulong |
0 ~ 18,446,744,073,709,551,615 |
부호 없는 64비트 정수 |
2. 다음 예제에서와 같이 ulong 변수를 선언하고 초기화할 수 있습니다.
ulong uLong = 9223372036854775808;
3. 정수 리터럴에 접미사가 없는 경우 해당 정수 리터럴의 형식은 그 밧이 표현될 수 있는 형식인 int,,uint, long, ulong 중에서 첫째 형식입니다.
4. 위 예제에서 정수 리터럴 형식은 ulong입니다.
5. 또한 다음 규칙에 따라 리터럴의 형식을 지정하는 접미사를 사용할 수 있습니다.
6. L 또는 l을 사용할 경우 리터럴의 형식은 그 크기에 따라 long 또는 ulong이 됩니다.
![]() |
---|
소문자 "l"도 접미사로 사용할 수 있습니다. 그러나 이 접미사는 숫자 "1"과 쉽게 혼동될 수 있기 때문에 컴파일러 경고가 발생합니다. 혼동을 피하려면 "L"을 사용하는 것이 좋습니다. |
7. U 또는 u를 사용할 경우 리터럴의 형식은 그 크기에 따라 uint 또는 ulong이 됩니다.
8. UL, ul, Ul, uL, LU, lu, Lu, lU를 사용할 경우 리터럴의 형식은 ulong이 됩니다.
9. 예를 들어, 다음과 같은 세 개의 문에 대한 출력은 ulong의 별칭에 해당하는 UInt64 시스템 형식이 됩니다.
Console.WriteLine(9223372036854775808L.GetType()); Console.WriteLine(123UL.GetType()); Console.WriteLine((123UL + 456).GetType());
10. 접미사는 오버로드된 메서드를 호출할 때 주로 사용됩니다.
11. 예를 들어 다음과 같이 ulong 및 int 매개 변수를 사용하는 오버로드된 메서드가 있습니다.
public static void SampleMethod(int i) {} public static void SampleMethod(ulong l) {}
12. 이 경우 ulong 매개 변수와 함께 접미사를 사용하면 올바른 형식이 호출됩니다.
SampleMethod(5); // Calling the method with the int parameter SampleMethod(5UL); // Calling the method with the ulong parameter
13. ulong에서 float, double 또는 decimal로의 암시적 변환이 미리 정의되어 있습니다.
14. ulong에서 다른 정수 계열 형식으로의 암시적 변환은 없습니다.
15. 예를 들어 명시적 캐스트를 사용하지 않으면 다음 문에서 컴파일 오류가 발생합니다.
long long1 = 8UL; // Error: no implicit conversion from ulong
16. byte, ushort, uint, char에서 ulong으로의 미리 정의된 암시적 변환이 있습니다.
17. 그러나 부동 소수점 형식에서 ulong으로의 암시적 변환은 없습니다.
18. 예를 들어 다음 문에서 명시적 캐스트를 사용하지 않으면 컴파일러 오류가 발생합니다.
// Error -- no implicit conversion from double: ulong x = 3.0; // OK -- explicit conversion: ulong y = (ulong)3.0;
19. 부동 소수점 형식 및 정수 계열 형식이 함께 사용되는 산술식에 대한 내용은 double 및 float을 참조하십시오.
20. 암시적 숫자 변환 규칙에 대한 자세한 내용은 암시적 숫자 변환 표를 참조하십시오.
unchecked
1. unchecked 키워드는 정수 계열 형식의 산술 연산 및 변환에 대한 오버플로 검사(overflow-checking)를 비활성화(suppress)하는 데 사용됩니다.
2. unchecked 컨텍스트 내에서는 식의 결과 값이 대상 형식(the destination type)의 범위를 벗어나는 경우, 오버플로 플래그가 세워지지 않습니다(the overflow is not flagged).
3. 예를 들어 다음 예제의 계산은 unchecked 블록이나 식의 안쪽에서 수행되므로 결과값이 정수로서는 너무 크다는 사실이 무시되고 int1에 값 -2,147,483,639이 할당됩니다.
unchecked { int1 = 2147483647 + 10; } int1 = unchecked(ConstantMax + 10);
4. unchecked 환경을 제거하면 컴파일 오류가 발생합니다.
5. 식의 모든 항(all the terms)이 상수이기 때문에 컴파일 시점에 오버플로를 감지(detect)할 수 있습니다.
6. 비상수 항(non-constant terms)을 포함하는 식은 기본적으로 컴파일 시점과 실행 시점에 검사되지 않습니다.
7. checked 환경을 사용하도록 설정하는 방법에 대한 자세한 내용은 checked를 참조하십시오.
8. 오버플로를 검사하는 작업은 시간이 걸리기 때문에, 오버플로 위험이 없는 경우 unchecked 코드를 사용하면 성능을 향상시킬 수 있습니다.
9. 그러나 오버플로가 발생할 수 있는 경우 checked 환경을 사용해야 합니다.
10. 이 샘플에서는 unchecked 키워드를 사용하는 방법을 보여줍니다.
class UncheckedDemo { static void Main(string[] args) { // int.MaxValue is 2,147,483,647. const int ConstantMax = int.MaxValue; int int1; int int2; int variableMax = 2147483647; // 다음 문은 기본적으로 컴파일 타임에 검사되므로 컴파일되지 않습니다. //int1 = 2147483647 + 10; //int1 = ConstantMax + 10; // int1 에 대입을 컴파일 가능하게 하고 실행하려면 // unchecked 블록이나 식 안에 둡니다. // 다음 문은 컴파일 되고 실행이 됩니다. unchecked { int1 = 2147483647 + 10; } int1 = unchecked(ConstantMax + 10); // 2,147,483,647 과 10 의 합은 -2,147,483,639 로 표시됩니다. Console.WriteLine(int1); // 식이 변수 variableMax 를 포함하므로 기본적으로 컴파일 타임에 검사되지 않습니다. // 그리고 오버플로가 일어나지만 오버플로가 감지되지 않습니다. // 다음 문은 컴파일 되고 실행 됩니다. int2 = variableMax + 10; // 다시, 2,147,483,647 과 10 의 합은 -2,147,483,639 로 표시됩니다. Console.WriteLine(int2); // 런 타임에 int2 에 대입에 대한 오버플로를 검사하려면 // checked 블록이나 식에 선언을 둡니다. // 다음 문은 컴파일 되지만 런 타임에 오버플로 예외가 발생합니다. checked { //int2 = variableMax + 10; } //int2 = checked(variableMax + 10); // Unchecked 섹션은 checked 환경에서 벗어나도록 빈번하게 사용됩니다. // 오버플로 예외가 없을 때 코드의 일부에서 성능 향상을 위해서 입니다. checked { // 오버플로 발생이 있을 수 있다면 checked 환경에서 실행되어야 합니다. unchecked { // 이 섹션은 오버플로가 없다고 확신할 때 // 그리고 성능이 중요할 때 절절합니다. } // 추가 checked 코드 } } }
unsafe
1. unsafe 키워드는 안전하지 않은 컨텍스트를 나타내며, 포인터에 관련된(involving pointers) 모든 작업에 필요합니다.
2. 자세한 내용은 안전하지 않은 코드 및 포인터를 참조하십시오.
3. 형식이나 멤버의 선언에 unsafe 한정자를 사용할 수 있습니다.
4. 따라서 형식이나 멤버의 전체 텍스트 범위(the entire textual extent)가 안전하지 않은 컨텍스트로 취급됩니다.
5. 예를 들어 다음 예제는 unsafe 한정자를 사용해 선언한 메서드입니다.
unsafe static void FastCopy(byte[] src, byte[] dst, int count) { // Unsafe context: can use pointers here. }
6. 안전하지 않은 컨텍스트의 범위(the scope)는 매개 변수 목록에서 메서드의 끝가지 확장(extend)되므로 매개 변수 목록에 포인터도 사용할 수 있습니다.
unsafe static void FastCopy ( byte* ps, byte* pd, int count ) {...}
7. 또한 안전하지 않은 블록을 사용해 이 블록 내에서 안전하지 않은 코드를 사용할 수도 있습니다.
unsafe { // Unsafe context: can use pointers here. }
8. 안전하지 않은 코드를 컴파일하려면 컴파일러 옵션 /unsafe를 지정해야 합니다.
9. 안전하지 않은 코드는 공용 언어 런타임으로 확인할 수 없습니다(is not verifiable).
// compile with: /unsafe class UnsafeTest { // 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); Console.WriteLine(i); } } // Output: 25
ushort
1. ushort 키워드는 다음 표에 표시된 크기와 범위에 따라 값을 저장하는 정수 계열 데이터 형식을 나타냅니다.
형식 |
범위 |
크기 |
.NET Framework 형식 |
---|---|---|---|
ushort |
0 ~ 65,535 |
부호 없는 16비트 정수 |
2. 다음 예제와 같이 ushort 변수를 선언하고 초기화할 수 있습니다.
ushort myShort = 65535;
3. 앞의 선언에서 정수 리터럴 65535는 암시적으로 int에서 ushort로 변환됩니다.
4. 정수 리터럴이 ushort 범위를 초과하면 컴파일 오류가 발생합니다.
5. 오버로드된 메서드를 호출할 경우 캐스트를 사용해야 합니다.
6. 예를 들어 다음과 같이 ushort 및 int 매개 변수를 사용하는 오버로드된 메서드가 있습니다.
public static void SampleMethod(int i) {} public static void SampleMethod(ushort s) {}
7. 이 경우 ushort 캐스트를 사용하면 올바른 형식이 호출됩니다.
// Calls the method with the int parameter: SampleMethod(5); // Calls the method with the ushort parameter: SampleMethod((ushort)5);
8. ushort에서 int, uint, long, ulong, float, double, decimal로의 미리 정의된 암시적 변환이 있습니다.
9. 또한 byte나 char에서 ushort로의 미리 정의된 암시적 변환이 있습니다.
10. 그 외의 다른 경우에는 캐스트를 사용하여 명시적 변환을 수행해야 합니다.
11. 예를 들어 다음과 같은 두 개의 ushort 변수 x 및 y가 있습니다.
ushort x = 5, y = 12;
12. 다음 할당문의 경우 할당 연산자의 오른쪽에 있는 산술식이 기본적으로 int로 계산되므로 컴파일 오류가 발생합니다.
ushort z = x + y; // Error: conversion from int to ushort
13. 이 문제를 해결하려면 캐스트를 사용하십시오.
ushort z = (ushort)(x + y); // OK: explicit conversion
14. 대상 변수의 저장소 크기가 같거나 더 클 경우에는 다음과 같은 문을 사용할 수 있습니다.
int m = x + y; long n = x + y;
15. 또한 부동 소수점 형식에서 ushort로의 암시적 변환은 없습니다.
16. 예를 들어 다음 문에서 명시적 캐스트를 사용하지 않으면 컴파일러 오류가 발생합니다.
// Error -- no implicit conversion from double: ushort x = 3.0; // OK -- explicit conversion: ushort y = (ushort)3.0;
17. 부동 소수점 형식 및 정수 계열 형식이 함께 사용되는 산술식에 대한 자세한 내용은 float 및 double을 참조하십시오.
18. 암시적 숫자 변환 규칙에 대한 자세한 내용은 암시적 숫자 변환 표를 참조하십시오.
using 지시문(Directive)
1. 네임스페이스의 별칭을 만들거나 다른 네임스페이스에 정의된 형식을 가져올 때(import) 지시문으로 사용할 수 있습니다.
2. using 지시문에는 다음 세 가지 용도(three uses)가 있습니다.
1) 네임스페이스에서 형식 사용을 한정할(qualify) 필요가 없도록 해당 네임스페이스에서 형식 사용을 허용합니다.
using System.Text;
2) 형식 이름을 사용하여 액세스를 한정할 필요 없이 형식의 정적 멤버에 액세스하도록 허용합니다.
using static System.Math;
3) 네임스페이스 또는 형식에 대한 별칭(an alias)을 만듭니다. 이를 using 별칭 지시문이라고 합니다.
using Project = PC.MyCompany.Project;
3. using 키워드는 파일 및 글꼴과 같은 IDisposable 개체가 제대로 처리될 수 있게 도와주는 using 문을 만드는 데도 사용됩니다.
4. 자세한 내용은 using 문을 참조하세요.
5. 형식 이름을 사용하여 액세스를 한정할 필요 없이 형식의 정적 멤버에 액세스할 수 있습니다.
using static System.Console; using static System.Math; class Program { static void Main() { WriteLine(Sqrt(3*3 + 4*4)); } }
namespace PC { // Define an alias for the nested namespace. using Project = PC.MyCompany.Project; class A { void M() { // Use the alias Project.MyClass mc = new Project.MyClass(); } } namespace MyCompany { namespace Project { public class MyClass { } } } }
using System; // Using alias directive for a class. using AliasToMyClass = NameSpace1.MyClass; // Using alias directive for a generic class. using UsingAlias = NameSpace2.MyClass<int>; namespace NameSpace1 { public class MyClass { public override string ToString() { return "You are in NameSpace1.MyClass."; } } } namespace NameSpace2 { class MyClass<T> { public override string ToString() { return "You are in NameSpace2.MyClass."; } } } namespace NameSpace3 { // Using directive: using NameSpace1; // Using directive: using NameSpace2; class MainClass { static void Main() { AliasToMyClass instance1 = new AliasToMyClass(); Console.WriteLine(instance1); UsingAlias instance2 = new UsingAlias(); Console.WriteLine(instance2); } } } // Output: // You are in NameSpace1.MyClass. // You are in NameSpace2.MyClass.
using 문
1. 개체의 범위를 정의할 때 문으로 사용할 수 있습니다.
2, 개체는 이 범위가 끝날 때 해제됩니다(dispose).
3. IDisposable 개체를 올바르게 사용할 수 있게 해 주는 편리한 구문(a convenient syntax)을 제공합니다.
4. 다음 예제에서는 using 문을 사용하는 방법을 보여 줍니다.
using (Font font1 = new Font("Arial", 10.0f)) { byte charset = font1.GdiCharSet; }
5. File 및 Font는 관리되지 않는 리소스(이 경우 파일 핸들 및 장치 컨텍스트)에 액세스하는 관리되는 형식의 예제입니다.
6. 관리되는 형식을 캡슐화하는 관리되지 않는 리소스 및 클래스 라이브러리 형식에는 여러 가지가 있습니다.
7. 이러한 모든 형식은 IDisposable 인터페이스를 구현해야 합니다.
8. 일반적으로(As a rule) IDisposable 개체를 사용할 때는 using 문에서 해당 개체를 선언하고 인스턴스화해야 합니다.
9. using 문은 개체의 Dispose 메서드를 올바른 방법으로 호출하며 앞에서 보여 준 것과 같이 사용할 경우 Dispose가 호출되면 즉시 해당 개체 자체가 범위를 벗어나도록 합니다.
10. using 문은 개체의 메서드를 호출(call methods on the object)하는 동안 예외가 발생하는 경우에도 Dispose가 호출되도록 합니다.
11. try 블록 내에 개체를 배치한 다음 finally 블록에서 Dispose를 호출해도 동일한 결과를 얻을 수 있습니다.
12. 이전의 코드 예제는 컴파일 타임에 다음 코드로 확장됩니다.
13. 중괄호를 추가하면 개체의 제한된 범위가 만들어 집니다.
{ Font font1 = new Font("Arial", 10.0f); try { byte charset = font1.GdiCharSet; } finally { if (font1 != null) ((IDisposable)font1).Dispose(); } }
using (Font font3 = new Font("Arial", 10.0f), font4 = new Font("Arial", 10.0f)) { // Use font3 and font4. }
Font font2 = new Font("Arial", 10.0f); using (font2) // not recommended { // use font2 } // font2 is still in scope // but the method call throws an exception float f = font2.GetHeight();
virtual
1. virtual 키워드는 메서드, 속성, 인덱서, 이벤트 선언을 한정(modify)하는 데 사용되며 파생 클래스에서 재정의될 수 있습니다.
2. 예를 들어 다음 메서드는 이 메서드를 상속하는 클래스에 의해 재정의될 수 있습니다.
public virtual double Area() { return x * y; }
3. 가상 멤버(a virtual member)의 구현은 파생 클래스의 override 멤버에 의해 변경될 수 있습니다.
4. virtual 키워드를 사용하는 방법에 대한 자세한 내용은 Override 및 New 키워드를 사용하여 버전 관리 및 Override 및 New 키워드를 사용해야 하는 경우를 참조하십시오.
5. 가상 메서드가 호출(invoke)되면 재정의 함수(an overring member)에 대해 개체의 런타임 형식이 검사(check)됩니다.
6. 가장 많이 파생되는 클래스의 재정의 멤버가 호출되므로 멤버가 멤버를 재정의한 파생 클래스가 없을 경우에는 원래 멤버가 호출될 수도 있습니다.
7. 기본적으로 메서드는 비 가상 메서드이며 비 가상 메서드는 재정의될 수 없습니다.
8. virtual 한정자는 static, abstract, private, override 한정자와 함께 사용할 수 없습니다.class MyBaseClass { // virtual auto-implemented property. Overrides can only // provide specialized behavior if they implement get and set accessors. public virtual string Name { get; set; } // ordinary virtual property with backing field private int num; public virtual int Number { get { return num; } set { num = value; } } } class MyDerivedClass : MyBaseClass { private string name; // Override auto-implemented property with ordinary property // to provide specialized accessor behavior. public override string Name { get { return name; } set { if (value != String.Empty) { name = value; } else { name = "Unknown"; } } } }
public Cylinder(double r, double h): base(r, h) {}
class TestClass { public class Shape { public const double PI = Math.PI; protected double x, y; public Shape() { } public Shape(double x, double y) { this.x = x; this.y = y; } public virtual double Area() { return x * y; } } public class Circle : Shape { public Circle(double r) : base(r, 0) { } public override double Area() { return PI * x * x; } } class Sphere : Shape { public Sphere(double r) : base(r, 0) { } public override double Area() { return 4 * PI * x * x; } } class Cylinder : Shape { public Cylinder(double r, double h) : base(r, h) { } public override double Area() { return 2 * PI * x * x + 2 * PI * x * y; } } static void Main() { double r = 3.0, h = 5.0; Shape c = new Circle(r); Shape s = new Sphere(r); Shape l = new Cylinder(r, h); // Display results: Console.WriteLine("Area of Circle = {0:F2}", c.Area()); Console.WriteLine("Area of Sphere = {0:F2}", s.Area()); Console.WriteLine("Area of Cylinder = {0:F2}", l.Area()); } } /* Output: Area of Circle = 28.27 Area of Sphere = 113.10 Area of Cylinder = 150.80 */
void
1. 메서드에 대한 반환 형식으로 사용하는 경우 void는 메서드가 값을 반환하지 않음을 지정합니다.
2. void 메서드의 매개 변수 목록에 사용할 수 없습니다.
3. 매개 변수가 없으면서 값을 반환하지 않는 메서드는 다음과 같이 선언됩니다.
public void SampleMethod() { // Body of the method. }
4. 또한 void는 알 수 없는 형식에 대한 포인터를 선언하기 위해 안전하지 않은 컨텍스트에서 사용합니다.
5. 자세한 내용은 포인터 형식을 참조하십시오.
6. void는 .NET Framework System.Void 형식의 별칭입니다.
volatile
1. volatile 키워드는 동시에 실행 중인 여러 스레드에 의해 필드가 수정될 수 있음을 나타냅니다.
2. volatile로 선언된 필드에는 단일 스레드를 통한 액세스를 전제로 하는 컴파일러 최적화가 적용되지 않습니다.
3. 이렇게 하면 필드의 값을 항상 최신 상태로(the most up-to-date) 유지할 수 있습니다.
4. 일반적으로 volatile 한정자는 액세스를 serialize할 때 lock 문을 사용하지 않고 여러 스레드에서 액세스하는 필드에 사용됩니다.
5. volatile 키워드는 다음과 같은 형식의 필드에 적용할 수 있습니다.
1) 참조 형식
2) 포인터 형식(unsafe context에서), 포인터 자체는 volatile일 수 있지만 포인터가 가리키는 개체는 volatile일 수 없습니다. 즉(In other words), "volatile 개체에 대한 포인터"를 선언할 수 없습니다.
3) sbyte, byte, short, ushort, int, uint, char, float 및 bool 같은 형식
4) 다음과 같은 기본 형식 중 하나를 사용하는 열거형 형식 : byte, sbyte, short, ushort, int, uint
5) 참조 형식으로 알려진 제네릭 형식 매개 변수
6. volatile 키워드는 클래스 또는 구조체의 필드에만 적용할 수 있습니다.
7. 지역 변수는 volatile로 선언할 수 없습니다.
8. 다음 예제에서는 public 필드 변수를 volatile로 선언하는 방법을 보여줍니다.
class VolatileTest { public volatile int i; public void Test(int _i) { i = _i; } }
9. 다음 예제에서는 보조(auxiliary) 또는 작업자(worker) 스레드를 만들고 기본 스레드(the primary)와 함께 이 스레드를 병렬로(in parallel with) 사용하여 작업 처리(processing)를 수행하는 방법을 보여 줍니다.
10. 다중 스레딩에 대한 배경 정보는 Managed Threading 및 스레딩을 참조하십시오.
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은 컴파일러에게 이 데이터 멤버는 다중 스레드가 액세스 한다는 것을 알립니다. 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. }
while
1. while 문은 지정된 식이 false가 될 때까지 하나의 문 또는 문 블록을 반복하여 실행합니다.
class WhileTest { static void Main() { int n = 1; while (n < 6) { Console.WriteLine("Current value of n is {0}", n); n++; } } } /* Output: Current value of n is 1 Current value of n is 2 Current value of n is 3 Current value of n is 4 Current value of n is 5 */
class WhileTest2 { static void Main() { int n = 1; while (n++ < 6) { Console.WriteLine("Current value of n is {0}", n); } } } /* Output: Current value of n is 2 Current value of n is 3 Current value of n is 4 Current value of n is 5 Current value of n is 6 */
2. 각 루프를 실행하기 전에 while 식을 테스트하기 때문에 while 루프는 0번 이상(zero or more times) 실행됩니다.
3. 이는 한 번 이상 실행되는 do 루프와 다른 부분입니다.
4. break, goto, return, throw 문이 제어를 루프 밖으로 전달할 때 while 루프를 종료(terminate)할 수 있습니다.
5. 루프를 종료하지 않고 다음 반복(the next iteration) 실행으로 제어를 전달하려면 continue 문을 사용합니다.
6. 위 세 개의 예제에서 출력은 int n이 증가(increment)되는 위치에 따라 달라집니다.
7. 다음 예제에서는 출력이 생성되지 않습니다.
class WhileTest3 { static void Main() { int n = 5; while (++n < 6) { Console.WriteLine("Current value of n is {0}", n); } } }
'프로그래밍 > C#' 카테고리의 다른 글
C# 기타 (0) | 2016.06.10 |
---|---|
C# 컨텍스트 키워드 (0) | 2016.06.06 |
C# 키워드 O~S (0) | 2016.05.31 |
C# 키워드 F~N (0) | 2016.05.21 |
C# 키워드 A-E (0) | 2016.05.13 |