달력

2

« 2025/2 »

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
2016. 5. 21. 15:14

C# 키워드 F~N 프로그래밍/C#2016. 5. 21. 15:14

false 연산자


1. 피연산자가 false를 나타낼 경우 bool값 true를 반환하고, 그렇지 않을 경우 false를 반환합니다.

2. C# 2.0 이전 버전에서는 true 및 false 연산자를 사용해서 SqlBool과 같은 형식과 호환되는 사용자 정의 nullable 값 형식을 만들었습니다.

3. 그러나 이 버전에서는 nullable 값 형식에 대한 지원이 기본적으로 제공되므로(built-in support), 가능하면 true 및 false 연산자를 오버로드하는 대신 nullable 값 형식을 사용해야 합니다.

4. 자세한 내용은 nullable 형식을 참조하십시오.

5. nullable Boolean으로 a != b 식은 두 값 중 하나 이상이 null일 수 있으므로 !(a==b)과 반드시 일치하지는 않습니다.

6. 식의 null 값을 올바르게 처리(handle)하려면 true 및 false 연산자를 개별적으로(separately) 오버로드해야 합니다.

7. 다음 예제에서는 true와 false 연산자를 오버로드하여 사용하는 방법을 보여줍니다.


// 예시용입니다. 가능하면 내장(built-in) nullable bool 형식(bool?)을 사용하세요. public struct DBBool { // 세 개의 가능한 DBBool 값들. public static readonly DBBool Null = new DBBool(0); public static readonly DBBool False = new DBBool(-1); public static readonly DBBool True = new DBBool(1); // False, Null, True에 대한 -1, 0, 1 을 저장하는 Private 필드 sbyte value; // Private 인스턴스 생상자 매개변수 값은 -1, 0, 1이어야 합니다. DBBool(int value) { this.value = (sbyte)value; } // DBBool의 값을 검사하는 속성. // 만약 DBBool 이 주어진 값을 가지고 있다면 true 반환, 그렇지 않으면 false 반환 public bool IsNull { get { return value == 0; } } public bool IsFalse { get { return value < 0; } } public bool IsTrue { get { return value > 0; } } // bool에서 DBBool로의 암시적 변환 // DBBool.True에 true를, DBBool.False에 false를 대입 public static implicit operator DBBool(bool x) { return x ? True : False; } // DBBool에서 bool로의 명시적 변환. // 주어진 DBBool이 Null이라면 예외를 Throw한다. 그렇지 않으면 true 또는 false 반환 public static explicit operator bool(DBBool x) { if (x.value == 0) throw new InvalidOperationException(); return x.value > 0; } // 균등 연산자(Equality operator). // 한 쪽 피연산자가 Null이면 Null 반환, 그렇지 않으면 True 또는 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 // 한 쪽 피연산자가 Null이면 Null 반환, 그렇지 않으면 True, 또는 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; } // 논리 부정 연산자. 피연산자가 False이면 True 반환 // 피연산자가 Null이면 Null 반환, 피연산자가 True이면 False 반환 public static DBBool operator !(DBBool x) { return new DBBool(-x.value); } // 논리 AND 연산자. Returns False if either operand is False, // 한 쪽 피연산자가 False이면 False 반환, Null이면 Null 반환, 그렇지 않으면 True 반환 public static DBBool operator &(DBBool x, DBBool y) { return new DBBool(x.value < y.value ? x.value : y.value); } // 논리 OR 연산자. 한 쪽 피연산자가 True이면 True 반환 // 한 쪽 피연산자가 Null이면 Null 반환. 그렇지 않으면 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 문과 조건식에서 제어식에 사용할 수 있습니다.

9. false 연산자를정의하는 형식은 true 연산자도 정의해야 합니다.

10. 한 형식으로 조건부 논리 연산자(&& 및 ||)를 직접 오버로드 할 수 없지만, 일반적인(regular) true 및 false 연산자를 오버로드하면 조건부 논리 연산자를 오버로드한 것과 같은 결과(equivalent effect)를 얻을 수 있습니다.





false 리터럴


1. boolean 값 false를 나타냅니다.


class TestClass
{
    static void Main() 
    {
        bool a = false;
        Console.WriteLine( a ? "yes" : "no" );
    }
}
// Output: no





try-finally


1. finally 블록을 사용하여 try 블록에 할당된 리소스를 정리(clean up)하고 try 블록에 예외가 발생하더라도 코드를 실행할 수 있습니다.

2. 일반적으로(typically), 제어가 try 문을 나갈 때 finally 블록 문이 실행됩니다.

3. 제어 이동은 일반 실행(normal execution), break, continue, goto, return 문 실행 또는 try 문에서 예외 전파(propagation)의 결과로 발생할 수 있습니다.

4. 처리된 예외(handled exception) 안에서는 연결된 finally 블록이 반드시 실행됩니다.(is guaranteed to be run)

5. 그러나 예외가 처리되지 않은 경우, finally 블록은 예외 해제 작업(exception unwind operation)이 트리거되는 방법에 따라 다르게 실행됩니다.

6. 이것도 컴퓨터 설정 방법에 따라 다릅니다.

7. 자세한 내용은 Unhandled Exception Processing in the CLR을 찹조하십시오.

8. 일반적으로(Usually), 처리되지 않은 예외로 응용 프로그램이 종료되면, finally 블록의 실행 여부는 중요하지 않습니다.

9. 그러나 이러한 상황에서도 실행되어야 하는 finally 블록의 문이 있는 경우 하나의 솔루션은 catch 블록을 try-finally 문에 추가하는 것입니다.

10. 또는(Alternatively), 높은 호출 스택(higher up the call stack)에 있는 try-finally의 try 블록에서 throw될 수 있는 예외를 catch할 수 있습니다.

11. try-finally 문이 포함된 메서드를 호출하는 메서드에서, 이 메서드를 호출하는 메서드에서 또는 호출 스택의 모든 메서드에서 예외를 catch할 수 있습니다.

12. 예외가 catch되지 않는 경우 finally 블록은 운영 체제에서 예외 해제 작업을 트리거하도록 선택하는지 여부에 따라 다르게 실행됩니다.

13. 아래 예제에서는 잘못된 변환문(an invalid conversion statement)이 System.InvalidCastException 예외를 발생시킵니다.

14. 예외는 처리되지 않습니다.


public class ThrowTestA { static void Main() { int i = 123; string s = "Some string"; object obj = s; try { // 잘못된 변환; obj는 숫자형(numeric type)이 아닌 문자열(string)을 포함한다. i = (int)obj; // 다음 문은 실행되지 않는다. Console.WriteLine("WriteLine at the end of the try block."); } finally { // Visual Studio에서 프로그램을 실행하려면 CTRL+F5를 누루세요. // 그리고 오류 창에서 취소를 클릭하세요. Console.WriteLine("\nExecution of the finally block after an unhandled\n" + "error depends on how the exception unwind operation is triggered."); Console.WriteLine("i = {0}", i); } } // Output: // Unhandled Exception: System.InvalidCastException: Specified cast is not valid. // // Execution of the finally block after an unhandled // error depends on how the exception unwind operation is triggered. // i = 123 }


15. 다음 예에서 TryCast 메서드의 예외는 호출 스택의 멀리 있는 메서드에서(in a method farther up the call stack) catch 됩니다.


public class ThrowTestB { static void Main() { try { // TryCast 처리되지 않은 예외를 발생시킵니다(produce). TryCast(); } catch (Exception ex) { // TryCast에서 처리되지 않은 예외를 catch 합니다. Console.WriteLine ("Catching the {0} exception triggers the finally block.", ex.GetType()); // 원래의 처리되지 않은 예외를 복구합니다. // 어떤 예외가 나타날지 어떻게 처리할지 모르기 때문에 예외를 throw합니다. throw; } } public static void TryCast() { int i = 123; string s = "Some string"; object obj = s; try { // 잘못된 변환, obj는 숫자 형식이 아닌 문자열을 포함합니다.. i = (int)obj; // 다음 문은 실행되지 않습니다. Console.WriteLine("WriteLine at the end of the try block."); } finally { // finally 블록이 실행되었음을 보여주고, // i의 값이 변경되지 않았음을 보여줍니다.. Console.WriteLine("\nIn the finally block in TryCast, i = {0}.\n", i); } } // Output: // In the finally block in TryCast, i = 123. // Catching the System.InvalidCastException exception triggers the finally block. // Unhandled Exception: System.InvalidCastException: Specified cast is not valid. }


16. finally에 대한 자세한 내용은 try-catch-finally를 참조하십시오.

17. C#에는 using 문도 포함(contain)됩니다.

18. 이 문은 간편한 구문(convenient syntax)에서 IDisposable 개체애 대해 비슷한 기능(similar functionality)을 제공합니다.





fixed 문


1. fixed 문은 가비지 수집기(garbage collector)에서 이동 가능한 변수(movable variable)를 재배치할 수 없도록 합니다.

2. fixed 문은 안전하지 않은 컨텍스트(an unsafe context)에서만 허용(permit)됩니다.

3. 또한 fixed는 고정 크기 버퍼(fixed size buffers)를 만드는 데 사용할 수도 있습니다.

4. fixed 문은 관리되는 변수(a managed variable)에 대한 포인터를 설정하고 문 실행 중에 해당 변수를 "고정"(pin)합니다.

5. fixed가 없으면 가비지 수집 시 변수가 예기치 않게(unpredictably) 재배치 될 수 있기 때문에 이동 가능한 관리되는 변수의 포인터는 거의 사용되지 않습니다(be of little use).

6. C# 컴파일러에서만 fixed 문에 관리되는 변수에 대한 포인터를 할당할 수 있습니다.


unsafe static void TestMethod()
{

    // Assume that the following class exists.
    //class Point 
    //{ 
    //    public int x;
    //    public int y; 
    //}

    // Variable pt is a managed variable, subject to garbage collection.
    Point pt = new Point();

    // Using fixed allows the address of pt members to be taken,
    // and "pins" pt so that it is not relocated.

    fixed (int* p = &pt.x)
    {
        *p = 1;
    }        

}


7. 배열, 문자열, 고정 크기 버퍼 또는 변수 주소를 사용하여 포인터를 초기화할 수 있습니다.

8. 다음 예제는 변수 주소, 배열, 문자열의 사용 방법을 보여줍니다.

9. 고정 크기 버퍼에 대한 자세한 내용은 고정 크기 버퍼를 참조하십시오.


static unsafe void Test2()
{
    Point point = new Point();
    double[] arr = { 0, 1.5, 2.3, 3.4, 4.0, 5.9 };
    string str = "Hello World";

    // The following two assignments are equivalent. Each assigns the address
    // of the first element in array arr to pointer p.

    // You can initialize a pointer by using an array.
    fixed (double* p = arr) { /*...*/ }

    // You can initialize a pointer by using the address of a variable. 
    fixed (double* p = &arr[0]) { /*...*/ }

    // The following assignment initializes p by using a string.
    fixed (char* p = str) { /*...*/ }

    // The following assignment is not valid, because str[0] is a char, 
    // which is a value, not a variable.
    //fixed (char* p = &str[0]) { /*...*/ } 


    // You can initialize a pointer by using the address of a variable, such
    // as point.x or arr[5].
    fixed (int* p1 = &point.x)
    {
        fixed (double* p2 = &arr[5])
        {
            // Do something with p1 and p2.
        }
    }
}


10. 포인터가 모두 같은 형식이라면 아래와 같이 여러 포인터를 초기화할 수 있습니다.


fixed (byte* ps = srcarray, pd = dstarray) {...}


11. 서로 다른 형식의 포인터를 초기화하려면 다음 예제와 같이 fixed 문을 중첩하기만 하면 됩니다.


fixed (int* p1 = &point.x)
{
    fixed (double* p2 = &arr[5])
    {
        // Do something with p1 and p2.
    }
}


12. 문의 코드가 실행된 후에는 고정된 모든 변수의 고정이 해제되어 가비지 수집 대상이 됩니다.

13. 따라서 fixed 문 밖에서 그러한 변수를 참조해서는 안 됩니다.


System_CAPS_note참고

fixed 문으로 초기화된 포인터는 수정할 수 없습니다.

14. unsafe 모드에서는 스택에 메모리를 할당할 수 있습니다.

15. 이러한 스택은 가비지 수집의 대상이 아니므로 고정할 필요가 없습니다.

16. 자세한 내용은 stackalloc을 참조하십시오.


class Point
{ 
    public int x, y; 
}

class FixedTest2 
{
    // Unsafe method: takes a pointer to an int.
    unsafe static void SquarePtrParam (int* p) 
    {
        *p *= *p;
    }

    unsafe static void Main() 
    {
        Point pt = new Point();
        pt.x = 5;
        pt.y = 6;
        // Pin pt in place:
        fixed (int* p = &pt.x) 
        {
            SquarePtrParam (p);
        }
        // pt now unpinned.
        Console.WriteLine ("{0} {1}", pt.x, pt.y);
    }
}
/*
Output:
25 6
 */





float


1. float 키워드는 32비트 부동 소수점 값을 저장하는 단순 형식을 나타냅니다.

2. 다음 표에서는 float 형식의 전체 자릿수와 근사 범위를 보여 줍니다.

형식

근사 범위

전체 자릿수 (Precision)

.NET Framework 형식

float

-3.4 × 1038to +3.4 × 1038

7개의 자릿수

System.Single

3. 기본적으로 할당 연산자의 오른쪽에 있는 실수형 숫자 리터럴은 double로 처리된다.

4. 따라서 float 형식의 변수를 초기화하려면 다음 예제와 같이 f 또는 F 접미사를 사용하십시요.


float x = 3.5F;


5. 위의 선언에서 접미사를 사용하지 않은 경우 float 변수에 double 값을 저장하려고 했으므로 컴파일 오류가 발생합니다.

6. 한 식에서 숫자 계열 형식과 부동 소수점 형식을 함께 사용할 수 있습니다.

7. 이 경우 정수 게열 형식은 부동 소수점 형식으로 변환됩니다.

    - 부동 소수점 형식 중 하나가 double인 경우 식은 double로 계산되거나, 관계식이거나 Boolean 식의 경우 bool로 계산됩니다. 

    - 식에 double 형식이 없는 경우, 식은 float로 계산되거나, 관계식이나 Boolean 식의 경우 bool로 계산됩니다.

8. 부동 소수점 식에는 다음과 같은 값이 포함될 수 있습니다.

    - 양수 및 음수 0

    - 양수 및 음수 무한

    - NaN(Not-a-Number) 값

    - 0이 아닌 값의 유한 집합

9. 이러한 값에 대한 자세한 내용은 IEEE 웹 사이트 IEEE Standard for Binary Floating-Point Arithmetic을 참조하십시오.

10. 다음 예제에서는 수학 식(mathematical expression)에 int, short, float가 포함되고 결과는 float가 됩니다.

11. float은 System.Single 형식의 별칭이라는 것을 기억하십시오.

12. 이 식에 double 형식은 없습니다.


class FloatTest 
{
    static void Main() 
    {
        int x = 3;
        float y = 4.5f;
        short z = 5;
        var result = x * y / z;
        Console.WriteLine("The result is {0}", result);
        Type type = result.GetType();
        Console.WriteLine("result is of type {0}", type.ToString());
    }
}
/* Output: 
  The result is 2.7
  result is of type System.Single //'float' is alias for 'Single'
 */





1. for 루프를 사용해서 지정된 식이 false로 평가될 때까지 반복적으로 하나의 문을 또는 문의 블록을 실행할 수 있습니다.

2. 이 종류의 loop는 배열을 반복하고 얼마나 반복할지 미리 알고 있는 다른 응용 프로그램에 유용합니다.

3. 다음 에제에서 i의 값을 콘솔에 작성하고, loop의 각 반복마다 1식 증가합니다.


class ForLoopTest 
{
    static void Main() 
    {
        for (int i = 1; i <= 5; i++)
        {
            Console.WriteLine(i);
        }
    }
}
/*
Output:
1
2
3
4
5
*/


4. 위의 예제에서 for 문은 다음 동작을 수행(perform)합니다.

    1) 첫째, 변수 i의 초기 값이 설정됩니다.

    2) 이 단계는 루프의 반복 횟수와 관계없이 한 번만 발생합니다.

    3) 이 초기화를 반복 과정의 외부에서 발생한다고 생각할 수 있습니다.

    4) 조건 (i <=5)를 평가하기 위해서 i의 값은 5와 비교됩니다.

    5) i가 5보다 작거나 같다면, 조건은 true로 계산되고, 다음 동작이 발생합니다.

        i) 루프의 본문의 Console.WriteLine 문이 i의 값은 표시합니다.

        ii) i의 값을 1씩 증가합니다.

        iii) 루프는 조건을 다시 계산하기 위해서 2단계의 시작으로 돌아갑니다.

    6) i가 5보다 크다면 조건은 false로 계산되고 루프를 종료(exit)합니다.

5. i의 초기 값이 5보다 크면 루프의 본문은 한번도 실행되지 않습니다.

6. 모든 for 문은 이니셜라이저, 조건, 반복기 섹션을 정의합니다.


for (initializer; condition; iterator)
    body


7. 일반적으로(usually) 이러한 섹션 루프의 반복 횟수를 결정합니다.

8. 섹션은 다음과 같은 목적으로 사용됩니다.

    1) 이니셜라이저 섹션은 초기 조건을 설정합니다.

    2) 루프로 들어가기 전에 이 섹션의 문은 한 번만 실행됩니다(run).

    3) 이 섹션은 다음 두 가지 옵션중 하나만 포함할 수 있습니다.

        i) 첫 예제(int i = 1)가 보여주듯, 지역 loop 변수의 선언과 초기화, loop에서 변수는 지역적이고 loop의 외부에서 접근할 수 없습니다.

        ii) 다음 목록에서 쉼표(commas)로 구분 된 0개 이상의 문 식 

            ㄱ) 할당 문(assignment statement)

            ㄴ) 메서드 호출(invocation of a method)

            ㄷ) ++i 또는 i++과 같은 전위 또는 후위 증가 식(increment expression)

            ㄹ) --i 또는 i--와 같은 전위 또는 후위 감소 식(decrement expression)

            ㅁ) new를 사용한 객체 생성(creation of an object by using new)

            ㅂ) await 식

        iii) 루프의 본문은 하나의 문 또는 빈 문 또는 문 블록(중괄호로 0개 이상의 문을 묶는)으로 구성됩니다.

        iv) break 키워드를 사용해서 for 루프를 빠져 나올 수 있습니다(break out of).

        v) continue 키워드를 사용해서 다음 반복으로 갈 수 있습니다(step to the next iteration).

        v) goto, return, throw 문을 사용해서 어떤 루프든지 끝낼 수 있습니다.

9. 첫 번째 예제에서는 가장 일반적인 종류의 for 루프(the most typical kind of for loop)를 보여주고 다음 선택을 합니다.

    1) 이니셜라이저는 로컬 루프 변수 i를 선언하고 초기화 합니다.

    2) 루프의 반복 횟수를 유지합니다(maintaion).

    3) 조건은 알려진 최종 값 5에 대해서(against) 루프 변수의 값을 검사합니다.

    4) 반복기 섹션은 후위 증가 문(postfix increment statement) i++를 사용하여 루프의 각 반복을 셉니다.

10. 다음 에제는 일반적이지 않은 선택 사항을 보여줍니다.

    1) 이니셜라이저 섹션에서 값을 외부 루프 변수에 할당

    2) 이니셜라이저와 반복기 섹션 모두에서 Console.WriteLine 메서드 호출

    3) 반복기 섹션에서 두 변수의 값을 변경


static void Main()
 {
     int i;
     int j = 10;
     for (i = 0, Console.WriteLine("Start: {0}",i); i < j; i++, j--, Console.WriteLine("i={0}, j={1}", i, j))
     {
         // Body of the loop.
     }
 }
 // Output:
 // Start: 0
 // i=1, j=9
 // i=2, j=8
 // i=3, j=7
 // i=4, j=6
 // i=5, j=5


11. for 문을 정의하는 모든 식은 선택 사항입니다.

12. 예를 들어 다음 문은 무한 루프를 만듭니다.


for (; ; )
{
    // ... 
}





foreach, in


1. foreach 문은 배열이나 System.Collections.IEnumerable 또는 System.Collections.Generic.IEnumerable<T> 인터페이스를 구현하는 개체 컬렉션에 있는 각 요소에 대해 포함(embedded) 문 그룹을 반복하여 실행합니다.

2. foreach 문은 컬렉션을 반복(iterate through) 실행하여 원하는 정보를 얻는 용도로 사용할 수 있지만 예측할 수 없는(unpredictable) 부작용(side effects)을 방지하면서 소스 컬렉션의 항목을 추가하거나 제거하는 용도로는 사용할 수 없습니다.

3. 소스 컬렉션에서 아이템을 추가하거나 제거하려면 for 루프를 사용하세요.

4. 배열 또는 컬렉션의 각 요소에 대해 포함 문(the embedded statements)이 계속 실행됩니다.

5. 컬렉션의 모든 요소에 대해 반복이 완료된 후에는 제어가 foreach 블록 아래의 다음 문으로 전달됩니다.

6. foreach 블록의 모든 위치에서(at any point) break 키워드를 사용해서 루프를 벗어나거나 continue 키워드를 사용해서 루프의 다음 반복으로 이동할 수 있습니다.

7. foreach 루프는 또한 goto, return, throw 문을 통해서 종료될 수 있습니다.

8. foreach 키워드에 대한 자세한 내용과 코드 예제는 다음 항목(topics)을 참조하십시오.

    - 배열에 foreach 사용

    - 방법 : foreach를 사용하여 컬렉션 클래스 액세스

9. 다음 코드에서는 세 가지 에제를 보여줍니다.

    - 정수 배열의 내용을 표시하는 일반적인(typically) foreach 루프입니다.

    - 동일한 기능을 수행하는 for 루프

    - 배열에 있는 요소의 수를 유지하는 foreach 루프


class ForEachTest { static void Main(string[] args) { int[] fibarray = new int[] { 0, 1, 1, 2, 3, 5, 8, 13 }; foreach (int element in fibarray) { System.Console.WriteLine(element); } System.Console.WriteLine(); // 이전 루프를 for 루프와 비교 for (int i = 0; i < fibarray.Length; i++) { System.Console.WriteLine(fibarray[i]); } System.Console.WriteLine(); // 컬렉션에서 요소의 수를 유지할 수 있다. int count = 0; foreach (int element in fibarray) { count += 1; System.Console.WriteLine("Element #{0}: {1}", count, element); } System.Console.WriteLine("Number of elements in the array: {0}", count); } // Output: // 0 // 1 // 1 // 2 // 3 // 5 // 8 // 13 // 0 // 1 // 1 // 2 // 3 // 5 // 8 // 13 // Element #1: 0 // Element #2: 1 // Element #3: 1 // Element #4: 2 // Element #5: 3 // Element #6: 5 // Element #7: 8 // Element #8: 13 // Number of elements in the array: 8 }





goto


1. goto 문은 프로그램의 제어를 레이블 문(labeled statement)으로 직접 전달(transfer)합니다.

2. 일반적으로(common) goto는 switch 문에서 특정 switch-case 레이블이나 기본 레이블로 제어를 전달하는 데 사용합니다.

3. 다음 예제에서는 switch 문에서 goto를 사용하는 방법을 보여 줍니다(demonstrate)


class SwitchTest
{
    static void Main()
    {
        Console.WriteLine("Coffee sizes: 1=Small 2=Medium 3=Large");
        Console.Write("Please enter your selection: ");
        string s = Console.ReadLine();
        int n = int.Parse(s);
        int cost = 0;
        switch (n)
        {
            case 1:
                cost += 25;
                break;
            case 2:
                cost += 25;
                goto case 1;
            case 3:
                cost += 50;
                goto case 1;
            default:
                Console.WriteLine("Invalid selection.");
                break;
        }
        if (cost != 0)
        {
            Console.WriteLine("Please insert {0} cents.", cost);
        }
        Console.WriteLine("Thank you for your business.");

        // Keep the console open in debug mode.
        Console.WriteLine("Press any key to exit.");
        Console.ReadKey();
    }
}
/*
Sample Input:  2

Sample Output:
Coffee sizes: 1=Small 2=Medium 3=Large
Please enter your selection: 2
Please insert 50 cents.
Thank you for your business.
*/

4. 아래 예제에서는 goto를 사용하여 중첩된(nested) 루프를 벗어나는 방법을 설명합니다.


public class GotoTest1
{
    static void Main()
    {
        int x = 200, y = 4;
        int count = 0;
        string[,] array = new string[x, y];

        // 배열 초기화:
        for (int i = 0; i < x; i++)

            for (int j = 0; j < y; j++)
                array[i, j] = (++count).ToString();

        // Read input:
        Console.Write("Enter the number to search for: ");

        // Input a string:
        string myNumber = Console.ReadLine();

        // Search:
        for (int i = 0; i < x; i++)
        {
            for (int j = 0; j < y; j++)
            {
                if (array[i, j].Equals(myNumber))
                {
                    goto Found;
                }
            }
        }

        Console.WriteLine("The number {0} was not found.", myNumber);
        goto Finish;

    Found:
        Console.WriteLine("The number {0} is found.", myNumber);

    Finish:
        Console.WriteLine("End of search.");


        // Keep the console open in debug mode.
        Console.WriteLine("Press any key to exit.");
        Console.ReadKey();
    }
}
/*
Sample Input: 44

Sample Output
Enter the number to search for: 44
The number 44 is found.
End of search.
*/





if-else


1. else 참조




implicit


1. implicit 키워드는 암시적인(implicit) 사용자 정의 형식 변환 연산자를 선언하는 데 사용됩니다.

2. 이 키워드를 사용하면 사용자 정의 형식과 다른 형식 간의 암시적인 변환이 가능합니다.

3. 변환이 변환으로 인해 데이터가 손실(a loss of data)되지 않는 경우에 한합니다.


class Digit { public Digit(double d) { val = d; } public double val; // ...other members // Digit 에서 double로의 사용자 정의 변환 public static implicit operator double(Digit d) { return d.val; } // double에서 Digit로의 사용자 정의 변환 public static implicit operator Digit(double d) { return new Digit(d); } } class Program { static void Main(string[] args) { Digit dig = new Digit(7); //This call invokes the implicit "double" operator double num = dig; //This call invokes the implicit "Digit" operator Digit dig2 = 12; Console.WriteLine("num = {0} dig2 = {1}", num, dig2.val); Console.ReadLine(); }

}


4. 암시적 변환은 불필요한 캐스트(unnecessary casts)를 제거하여(eliminate), 소스 코드를 읽기 쉽도록(readability) 합니다.

5. 그러나 암서적 변환을 수행할 때는 프로그래머가 한 형식을 다른 형식으로 명시적으로 캐스팅할 필요가 없으므로 예기치 않은(unexpected) 결과가 발생하지 않도록 주의해야 합니다(care must be taken to V).

6. 일반적으로(In general) 프로그래머가 개입하지 않고(without the programmer's awareness) 암시적 변환 연산자를 안전하게 사용하려면 해당 연산자에서 예외를 throw하거나 정보가 손실(lose information)되지 않도록 해야 합니다.

7. 변환 연산자가 이러한 기준(those criteria)을 충족(meet)시키지 못하는 경우 연산자를 explicit로 표시(marked)해야 합니다.

8. 자세한 내용은 변환 연산자 사용을 참조하십시오.





in


1. foreach 참조




in(제네릭 한정자)


1. 제네릭 형식 매개 변수의 경우 in 키워드는 형식 매개 변수가 반공변(contravariant)임을 나타냅니다.

2. 제네릭 인터페이스와 대리자에서 in 키워드를 사용할 수 있습니다.

3. 반공변성(contravariance)을 사용하면 제네릭 매개 변수로 지정된 형식보다 더 적게 파생된 형식을 사용할 수 있습니다.

4. 이 경우 variant 인터페이스를 구현하는 클래스의 암시적 변환과 대리자 형식의 암시적 변환이 가능합니다.

5. 제네릭 형식 매개 변수의 공 분산(covariance)과 반공 분산(contravariance)은 참조 형식에만 지원되고 값 형식에는 지원되지 않습니다.

6. 형식이 메서드 인수의 형식으로만 사용되고 메서드 반환 형식으로는 사용되지 않는 경우 제네릭 인터페이스 또는 대리자에서 형식이 반공변(contravariant)으로 선언될 수 있습니다.

7. Ref 및 out 파라미터는 variant가 될 수 없습니다.

8. 반공변(contravariant) 형식 매개 변수가 있는 인터페이스의 메서드는 인터페이스 형식 매개 변수로 지정된 형식보다 더 적게 파생된 형식의 인수를 사용할 수 있습니다.

9. 예를 들어, .NET Framework 4의 IComparer<T> 인터페이스에서 형식 T는 반공변(contravariant)이므로 Employee가 Person를 상속(inherit)하는 경우 특수 변환 메서드를 사용하지 않고도 IComparer(Of Person) 형식의 개체를 IComparer(Of Employee) 형식의 개체에 할당할 수 있습니다.

10. 형식이 같고 더 적게 파생된 형식 매개 변수를 사용하는 다른 대리자에 반공변(contravariant) 대리자를 할당할 수 있습니다.

11. 자세한 내용은 공 분산 및 반공 분산을 참조하십시오.

12. 다음 예제에서는 반공변(contravariant) 제네릭 인터페이스를 선언, 확장 및 구현하는 방법을 보여줍니다.

13. 또한 이 인터페이스를 구현하는 클래스의 암시적 변환을 사용하는 방법도 보여줍니다


// Contravariant interface.
interface IContravariant<in A> { }

// Extending contravariant interface.
interface IExtContravariant<in A> : IContravariant<A> { }

// Implementing contravariant interface.
class Sample<A> : IContravariant<A> { }

class Program
{
    static void Test()
    {
        IContravariant<Object> iobj = new Sample<Object>();
        IContravariant<String> istr = new Sample<String>();

        // You can assign iobj to istr because
        // the IContravariant interface is contravariant.
        istr = iobj;
    }
}


14. 다음 예제에서는 반공변(contravariant) 제네릭 대리자를 선언, 인스턴스화 및 호출하는 방법을 보여 줍니다.

15. 또한 대리자 형식을 암시적으로 변환하는 방법도 보여 줍니다.


// Contravariant delegate.
public delegate void DContravariant<in A>(A argument);

// Methods that match the delegate signature.
public static void SampleControl(Control control)
{ }
public static void SampleButton(Button button)
{ }

public void Test()
{

    // Instantiating the delegates with the methods.
    DContravariant<Control> dControl = SampleControl;
    DContravariant<Button> dButton = SampleButton;

    // You can assign dControl to dButton
    // because the DContravariant delegate is contravariant.
    dButton = dControl;

    // Invoke the delegate.
    dButton(new Button()); 
}





int


1. int 키워드는 다음 표에 표시된 크기와 범위에 따라 값을 저장하는 정수 계열 형식을 나타냅니다(denote).

형식

범위

크기

.NET Framework 형식

기본값

int

-2,147,483,648 ~ 2,147,483,647

부호 있는 32비트 정수

System.Int32

0

2. 다음 예제에서와 같이 int 형식 변수를 선언하고 초기화할 수 있습니다.


int i = 123;


3. 정수 리터럴에 접미사가 없는 경우 해당 정수 리터럴의 형식은 그 값이 표현될 수 있는 형식이 int, uint, long, ulong 중에서 첫째 형식입니다(the first of these types).

4. 이 예제에서 정수 리터럴의 형식은 int입니다.

5. int에서 long, float, double 또는 decimal로의 미리 정의된 암시적 변환이 있습니다.


// '123' 이 int이므로 암시적 변환이 일어납니다. float f = 123;


6. sbyte, byte, short, ushort 또는 char에서 int로의 암시적 변환이 미리 정의되어 있습니다.

7. 예를 들어 캐스트를 사용하지 않으면(without a cast) 다음 대입문(the following assignment statement)에서 컴파일 오류가 발생합니다(produce a compilation error).


long aLong = 22;
int i1 = aLong;       // Error: no implicit conversion from long.
int i2 = (int)aLong;  // OK: explicit conversion.


8. 또한 부동 소수점 형식(floating-point types)에서 int로의 암시적 변환은 없습니다.

9. 예를 들어 다음 문에서 명시적 캐스트를 사용하지 않으면 컴파일러 오류가 발생합니다(generate a compiler error)


int x = 3.0;         // Error: no implicit conversion from double.
int y = (int)3.0;    // OK: explicit conversion.


10. 부동 소수점 형식 및 정수 계열 형식이 함께 사용되는 산술식(arithmetic expressions)에 대한 자세한 내용은 float 및 double를 참조하십시오.





interface


1. 인터페이스에는 메서드, 속성(properties), 이벤트, 인덱서의 시그니처만 포합됩니다.

2. 인터페이스를 구현하는 클래스나 구조체는 인터페이스의 정의(definition)에 지정된 인터페이스 멤버를 구현해야 합니다.

3. 다음 예제에서는 ImplementationClass 클래스가 매개 변수를 사용하지 않고 void를 반환하는 SampleMethod 메서드를 구현해야 합니다.

4. 자세한 내용과 예제를 보려면 인터페이스를 참조하십시오.


interface ISampleInterface { void SampleMethod(); } class ImplementationClass : ISampleInterface { // 명시적 인터페이스 멤버 구현: void ISampleInterface.SampleMethod() { // 메서드 구현 } static void Main() { // 인터페이스 인스턴스 선언. ISampleInterface obj = new ImplementationClass(); // 멤버 호출. obj.SampleMethod(); } }


5. 인터페이스는 네임스페이스 또는 클래스의 멤버가 될 수 있으며 다음 멤버의 시그니처를 포함할 수 있습니다.

    - 메서드, 속성, 인덱서, 이벤트

6. 인터페이스는 하나 이상의 기본 인터페이스(base interfaces)에서 상속할 수 있습니다.

7. 기본 형식 목록에 기본 클래스와 인터페이스가 있는 경우 기본 클래스가 목록의 처음에 있어야 합니다.

8. 인터페이스를 구현하는 클래스는 해당 인터페이스의 멤버를 명시적으로 구현할 수 있습니다.

9. 명시적으로 구현된 멤버는 클래스 인스턴스를 통해 액세스할 수 없고 인터페이스의 인스턴스를 통해서만 액세스할 수 있습니다.

10. 명시적 인터페이스 구현에 대한 자세한 내용과 코드 예제는 명시적 인터페이스 구현을 참조하십시오.

11. 다음 예제에서는 인터페이스 구현  방법을 보여 줍니다(demonstrate).

12. 이 예제에서 인터페이스에는 속성 선언이 포함되고 클래스에는 구현이 포함됩니다.

13. IPoint를 구현하는 클래스 인스턴스에 정수 속성(integer properties) x 및 y가 있습니다.


interface IPoint { // 속성 시그니처: int x { get; set; } int y { get; set; } } class Point : IPoint { // 필드: private int _x; private int _y; // 생성자: public Point(int x, int y) { _x = x; _y = y; } // 속성 구현: public int x { get { return _x; } set { _x = value; } } public int y { get { return _y; } set { _y = value; } } } class MainClass { static void PrintPoint(IPoint p) { Console.WriteLine("x={0}, y={1}", p.x, p.y); } static void Main() { Point p = new Point(2, 3); Console.Write("My Point: "); PrintPoint(p); } } // Output: My Point: x=2, y=3






internal


1. internal 키워드는 형식 및 형식 멤버에 대한 액세스 한정자(access modifier) 입니다.

2;. internal 타입이나 멤버는 다음 예제와 같이 동일한 어셈블리의 파일 내에서만 액세스할 수 있습니다.


public class BaseClass 
{
    // Only accessible within the same assembly
    internal static int x = 0;
}


3. 액세스 한정자 protected internal이 있는 형식이나 멤버는 현재 어셈블리 또는 포함하는 클래스에서 파생된 형식에서 액세스할 수 있습니다.

4. internal을 다른 액세스 한정자와 비교하려면 액세스 가능성 수준액세스 한정자를 참조하십시오.

5. 어셈블리에 대한 자세한 내용은 어셈블리와 전역 어셈블리 캐시를 참조하십시오.

6. 내부 액세스는 구성 요소 그룹이 나머지 응용 프로그램 코드(the rest of the application code)에 노출(exposed)되지 않으면서 상호 작용할 수(cooperate in a private manner) 있도록 하기 때문에 구성 요소 기반 개발(component-based development)에 주로 사용됩니다.

7. 예를 들어 그래픽 사용자 인터페이스를 빌드하기 위한 프레임워크는 내부 액세스가 지정된 멤버를 사용하여 상호 작용하는 Control 및 Form 클래스를 제공할 수 있습니다.

8. 이 멤버들은 내부 멤버이기 때문에 프레임워크를 사용하는 코드에 노출되지 않습니다.

9. 내부 액세스 형식 또는 멤버를 해당 형식 또는 멤버가 정의된 어셈블리 외부에서 참조(reference)하면 오류가 발생합니다.

10. 다음 예제에서는 두 개의 파일 Assembly1.cs 및 Assembly1_a.cs가 포함되어 있습니다.

11. 첫 번째 파일에는 내부 기본 클래스 BaseClass가 있습니다.

12. 두 번째 파일에서 BaseClass를 인스턴스화하려고 시도하면 오류가 발생합니다.


// Assembly1.cs
// Compile with: /target:library
internal class BaseClass 
{
   public static int intM = 0;
}


// Assembly1_a.cs
// Compile with: /reference:Assembly1.dll
class TestAccess 
{
   static void Main() 
   {
      BaseClass myBase = new BaseClass();   // CS0122
   }
}


13. 다음 예제에서는 예제 1에 사용한 것과 같은 파일을 사용하되 BaseClass의 액세스 수준(the accessibility level)을 public으로 변경합니다.

14. 또한 IntM 멤버의 액세스 수준을 internal로 변경합니다.

15. 이 경우 클래스를 인스턴스화할 수는 있지만 내부 멤버에 액세스할 수는 없습니다.


// Assembly2.cs
// Compile with: /target:library
public class BaseClass 
{
   internal static int intM = 0;
}


// Assembly2_a.cs
// Compile with: /reference:Assembly1.dll
public class TestAccess 
{
   static void Main() 
   {
      BaseClass myBase = new BaseClass();   // Ok.
      BaseClass.intM = 444;    // CS0117
   }
}





is


1. 지정된 형식(a given type)과 개체가 호환되는지(compatible with) 검사합니다(check).

2. 예를 들어 다음 코드에서는 개체가 MyObject 형식의 인스턴스이거나 MyObject에서 파생 형식인지 확인할(determine) 수 있습니다.


if (obj is MyObject)
{
}


3. 지정된 식이 null이 아니고(non-null) 예외를 throw하지 않은 채 지정된 개체를 지정된 형식으로 캐스팅할 수 있는 경우 is 식은 true가 됩니다.

4. 식이 항상 true이거나 항상 false인 것으로 알려져 있는 경우 is 키워드는 컴파일 타임 경고를 발생시키지만 런타임에는 일반적으로(typically) 형식 호환성을 확인합니다.

5. is 연산자는 오버로드되지 않습니다.

6. is 연산자는 참조 변환, boxing 변환 및 unboxing 변환만 고려합니다.

7. 사용자 정의 변환 같은 다른 변환은 고려되지 않습니다.

8. 무명 메서드는 is 연산자의 왼쪽에 사용할 수 없습니다.

9. 이 예외에는 lambda 식이 포함됩니다.


class Class1 {}
class Class2 {}
class Class3 : Class2 { }

class IsTest
{
    static void Test(object o)
    {
        Class1 a;
        Class2 b;

        if (o is Class1)
        {
            Console.WriteLine("o is Class1");
            a = (Class1)o;
            // Do something with "a."
        }
        else if (o is Class2)
        {
            Console.WriteLine("o is Class2");
            b = (Class2)o;
            // Do something with "b."
        }
        else
        {
            Console.WriteLine("o is neither Class1 nor Class2.");
        }
    }
    static void Main()
    {
        Class1 c1 = new Class1();
        Class2 c2 = new Class2();
        Class3 c3 = new Class3();
        Test(c1);
        Test(c2);
        Test(c3);
        Test("a string");
    }
}
/*
Output:
o is Class1
o is Class2
o is Class2
o is neither Class1 nor Class2.
*/





lock


1. lock 키워드는 지정된 객체를 상호 배타적(mutual-exclusion)으로 잠그고 문을 실행한 다음 잠금을 해제함으로써 문 블럭을 임계 영역(critical section)으로 표시합니다.

2. 다음 예제에서는 lock 문을 포함합니다.


class Account
{
    decimal balance;
    private Object thisLock = new Object();

    public void Withdraw(decimal amount)
    {
        lock (thisLock)
        {
            if (amount > balance)
            {
                throw new Exception("Insufficient funds");
            }
            balance -= amount;
        }
    }
}


3. 자세한 내용은 스레드 동기화를 참조하십시오.

4. lock 키워드를 사용하면 다른 스레드가 코드의 임계 영역에 있는 동안에는 특정 스레드가 임계 영역에 들어갈 수 없습니다.

5. 다른 스레드가 잠긴 코드에 들어가려고 할 경우 개체가 해제(release)될 때까지 대기합니다.

6. 스레딩에 대한 자세한 내용은 스레딩 단원을 참조하십시오.

7. lock 키워드는 블록의 시작 부분에서 Enter를 호출하고 블록의 끝 부분에서 Exit를 호출합니다.

8. 인터럽트가 lock 문에 들아가려고 대기하고 있는 스레드에 인터럽트 한다면 ThreadInterruptedException 가 throw됩니다.

9. 일반적으로 코드에서 제어되지 않는 인스턴스나 public 형식은 잠그지 않는 것이 좋습니다.

10. 일반적인 구문)constructs) lock (this), lock (typeof (MyType)) 및 lock("myLock")은 다음과 같이 이 지침을 위반합니다.

    1) lock (this) - 해당 인스턴스에 공용으로 액세스할 수 있는 경우 문제가 됩니다.

    2) lock (typeof (MyType)) - MyType에 공용으로 액세스할 수 있는 경우 문제가 됩니다.

    3) lock("myLock") - 동일한 문자열을 사용하는 프로세스의 다른 코드가 동일한 잠금을 공유하게 되므로 문제가 됩니다.

11. 가장 좋은 방법(Best practice)은 private 개체를 정의하여 잠그거나 private static 개체 변수를 정의하여 모든 인스턴스에 공통된(common) 데이터를 보호하는 것입니다.

12. lock 문의 본문에 await 키워드를 사용할 수 없습니다.

13. 다음 샘플에서는 C#에서 잠금 없이 스레드를 사용하는 간단한 방법을 보여줍니다.


//using System.Threading;

class ThreadTest
{
    public void RunMe()
    {
        Console.WriteLine("RunMe called");
    }

    static void Main()
    {
        ThreadTest b = new ThreadTest();
        Thread t = new Thread(b.RunMe);
        t.Start();
    }
}
// Output: RunMe called


14. 다음 샘플에서는 스레드와 lock을 사용합니다.

15. lock 문이 있으면(is present), 문 블록이 임계 영역이 되고 balance는 음수(a negative number)가 되지 않습니다.


// using System.Threading;

class Account
{
    private Object thisLock = new Object();
    int balance;

    Random r = new Random();

    public Account(int initial)
    {
        balance = initial;
    }

    int Withdraw(int amount)
    {

        // This condition never is true unless the lock statement
        // is commented out.
        if (balance < 0)
        {
            throw new Exception("Negative Balance");
        }

        // Comment out the next line to see the effect of leaving out 
        // the lock keyword.
        lock (thisLock)
        {
            if (balance >= amount)
            {
                Console.WriteLine("Balance before Withdrawal :  " + balance);
                Console.WriteLine("Amount to Withdraw        : -" + amount);
                balance = balance - amount;
                Console.WriteLine("Balance after Withdrawal  :  " + balance);
                return amount;
            }
            else
            {
                return 0; // transaction rejected
            }
        }
    }

    public void DoTransactions()
    {
        for (int i = 0; i < 100; i++)
        {
            Withdraw(r.Next(1, 100));
        }
    }
}

class Test
{
    static void Main()
    {
        Thread[] threads = new Thread[10];
        Account acc = new Account(1000);
        for (int i = 0; i < 10; i++)
        {
            Thread t = new Thread(new ThreadStart(acc.DoTransactions));
            threads[i] = t;
        }
        for (int i = 0; i < 10; i++)
        {
            threads[i].Start();
        }
    }
}

 



long


1. long 키워드는 다음 표에 표시된 크기와 범위에 따라 값을 저장하는 정수 계열 형식을 나타냅니다.

형식

범위

크기

.NET Framework 형식

long

–9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807

부호 있는 64비트 정수

System.Int64

2. 다음 예제에서와 같이 long 변수를 선언하고 초기화할 수 있습니다.


long long1 = 4294967296;


3. 정수 리터럴에 접미사가 없는 경우 해당 정수 리터럴의 형식은 그 값이 표현될 수 있는 형식인 int, uint, long, ulong 중에서 첫째 형식입니다.

4. 앞의 예에서 정수 리터럴의 형식은 uint 범위를 초과하기 때문에 long입니다.

5. 정수 게열 형식의 저장  크기에 대해서는 정수 계열 형식 표를 참조하십시오.

6. 또한 다음과 같이 long 형식에 L 접미사를 사용할 수도 있습니다.


long long2 = 4294967296L;


7. L 접미사를 사용할 경우 리터럴 형식은 크기에 따라 long 또는 ulong으로 결정됩니다.

8. 위의 경우 리터럴 정수는 ulong 범위보다 작기 때문에 long 형식입니다.

9. 접미사는 오버로드된 메서드를 호출할 때 주로 사용됩니다.

10. 예를 들어 다음과 같이 long 및 int 매개 변수를 사용하는 오버로드된 메서드가 있습니다.


public static void SampleMethod(int i) {}
public static void SampleMethod(long l) {}


11. 이 경우, L 접미사를 사용하면 올바른 형식이 호출됩니다.


SampleMethod(5);    // Calling the method with the int parameter
SampleMethod(5L);   // Calling the method with the long parameter


12. 같은 식에서 다른 숫자 정수 계열 형식과 함께 long 형식을 사용할 수 있습니다.

13. 이런 경우  long으로 계산되고 부울 식 또는 관계식의 경우에는 bool로 계산됩니다.

14. 예를 들어 다음 식은 long으로 계산됩니다.


898L + 88


System_CAPS_note참고

소문자 "l"도 접미사로 사용할 수 있습니다. 그러나 이 접미사는 숫자 "1"과 쉽게 혼동될 수 있기 때문에 컴파일러 경고가 발생합니다. 혼동을 피하려면(for clarity) "L"을 사용하는 것이 좋습니다.

15. 부동 소수점 형식 및 정수 게열 형식이 함께 사용되는 산술식에 대한 내용은 double 및 float을 참조하십시오.

16. long에서 float, double 또는 decimal로의 암시적 변환이 미리 정의되어 있습니다.

17. 그 외의 다른 경우에는 캐스트를 사용해야 합니다

18. 예를 들어, 명시적 캐스트를 사용하지 않으면 다음  문에서 컴파일 오류가 발생합니다.


int x = 8L;        // Error: no implicit conversion from long to int
int x = (int)8L;   // OK: explicit conversion to int


19. sbyte, byte, short, ushort, int, uint 또는 char에서 long으로의 암시적 변환이 미리 정의되어 있습니다.

20. 또한 부동 소수점 형식에서 long으로의 암시적 변환은 없습니다.

21. 예를 들어, 다음 문에서 명시적 캐스트를 사용하지 않으면 컴파일러 오류가 발생합니다.


long x = 3.0;         // Error: no implicit conversion from double
long y = (long)3.0;   // OK: explicit conversion





namespace


1. namespace 키워드를 사용하여 관련된 개체 집합이 포함된 범위를 선언합니다.

2. 네임스페이스 코드 요소를 구성하고 전역적으로 고유한 형식(globally unique types)을 만들 수 있습니다.


namespace SampleNamespace
{
    class SampleClass { }

    interface SampleInterface { }

    struct SampleStruct { }

    enum SampleEnum { a, b }

    delegate void SampleDelegate(int i);

    namespace SampleNamespace.Nested
    {
        class SampleClass2 { }
    }
}


3. 네임스페이스 내에서 아래와 같은 형식을 하나 이상 선언할 수 있습니다.

    1) 기타 네임스페이스(another namespace)

    2) class

    3) interface

    4) struct

    5) enum

    6) 대리자(delegate)


4. C# 소스 파일에 네임스페이스를 명시적으로 선언하든 그렇지 않든 관계없이 컴파일러에서는 기본 네임스페이스를 추가합니다.

5. 명명되지 않은 이 네임스페이스는 전역 네임스페이스라고도 하며 모든 파일에 존재합니다(is present).

6. 전역 네임스페이스(global namespace)의 모든 식별자(Any identifier)는 명명된 네임스페이스에서 사용할 수 있습니다.

7. 네임스페이스는 암시적으로(implicitly) 공용 액세스이며 수정할 수는 없습니다(is not modifiable).

8. 네임스페이스의 요소에 할당할 수 있는 액세스 한정자에 대한 자세한 내용은 액세스 한정자를 참조하십시오.

9. 두 개 이상의 선언에서 네임스페이스를 정의할 수 있습니다.

10. 예를 들어, 다음 예제에서는 두 클래스를 모두 MyCompany 네임스페이스의 일부로 정의합니다.


namespace MyCompany.Proj1
{
    class MyClass
    {
    }
}

namespace MyCompany.Proj1
{
    class MyClass1
    {
    }
}


11. 아래 예제에서는 중첩된 네임스페이스에서 정적 메서드를 호출하는 방법을 보여줍니다.


namespace SomeNameSpace
{
    public class MyClass 
    {
        static void Main() 
        {
            Nested.NestedNameSpaceClass.SayHello();
        }
    }

    // a nested namespace
    namespace Nested   
    {
        public class NestedNameSpaceClass 
        {
            public static void SayHello() 
            {
                Console.WriteLine("Hello");
            }
        }
    }
}
// Output: Hello


12. 네임스페이스 사용에 대한 자세한 내용은 다음 항복을 참조하십시오.

    1) 네임스페이스

    2) 네임스페이스 사용

    3) 방법: 전역 네임스페이스 별칭 사용





new 연산자


1. 개체를 만들고 생성자를 호출하는 데 사용됩니다.


Class1 obj  = new Class1();


2. 이는 익명 형식의 인스턴스를 만드는 데도 사용됩니다.


var query = from cust in customers
            select new {Name = cust.Name, Address = cust.PrimaryAddress};


3. 또한 new 연산자는 값 형식에 대한 기본 생성자를 호출하는 데도 사용됩니다.


int i = new int();


4. 앞의 문에서 i는 int 형식의 기본값인 0으로 초기화됩니다.

5. 앞의 문의 결과는 다음 문의 결과와 같습니다.


int i = 0;


6. 기본값의 전체 목록을 보려면 기본값 표를 참조하십시오.

7. 모든 값 형식에는 암시적으로 공용 기본 생성자(a public default constructor)가 포함되기 때문에 구조체에 대한 기본 생성자를 선언하면 오류가 발생합니다.

8. 구조체 형식에 대해 매개변수가 있는 생성자(parameterized constructors)를 선언하여 그 초기 값을 설정할 수 있지만 이 방법은 기본값이 아닌 다른 값이 필요한 경우에만 사용해야 합니다.

9. 구조체와 같은 값 형식 개체는 스택에 만들어지고 클래스 같은  참조 형식 개체는 에 만들어집니다.

10. 두 형식의 개체는 모두 자동으로 소멸됩니다.

11. 두 형식의 개체는 모두 자동으로 소멸됩니다.

12. 그러나 값 형식을 기반으로 한 개체는 범위를 벗어날 때 소멸되는 반면 참조 형식을 기반으로 한 개체는이에 대한 마지막 참조를 제거한 후에 지정되지 않은 임의의 시간에(at an unspecified time) 소멸된다는점에서 차이가 있습니다.

13. 많은 용량의 메모리, 파일 핸들 또는 네트워크 연결 같은 고정된 리소스 사용하는 참조 형식의 경우 개체가 가능한 한 빨리 소멸되도록 명확한 종료 방식(deterministic finalization)을 사용하(employ)는 것이 좋을 수도 있습니다.

14. new 연산자는 오버로드되지 않습니다.

15. new 연산자가 메모리 할당에 실패하면 OutOfMemoryException 예외를 throw합니다.

16. 다음 예제에서는 new 연산자를 사용하여 struct 개체 및 클래스 개체를 만들어 초기화한 다음 값을 대입합니다.

17. 그러면 기본값과 할당된 값이 표시됩니다.


struct SampleStruct
{
   public int x;
   public int y;

   public SampleStruct(int x, int y)
   {
      this.x = x;
      this.y = y;
   }
}

class SampleClass
{
   public string name;
   public int id;

   public SampleClass() {}

   public SampleClass(int id, string name)
   {
      this.id = id;
      this.name = name;
   }
}

class ProgramClass
{
   static void Main()
   {
      // Create objects using default constructors:
      SampleStruct Location1 = new SampleStruct();
      SampleClass Employee1 = new SampleClass();

      // Display values:
      Console.WriteLine("Default values:");
      Console.WriteLine("   Struct members: {0}, {1}",
             Location1.x, Location1.y);
      Console.WriteLine("   Class members: {0}, {1}",
             Employee1.name, Employee1.id);

      // Create objects using parameterized constructors:
      SampleStruct Location2 = new SampleStruct(10, 20);
      SampleClass Employee2 = new SampleClass(1234, "Cristina Potra");

      // Display values:
      Console.WriteLine("Assigned values:");
      Console.WriteLine("   Struct members: {0}, {1}",
             Location2.x, Location2.y);
      Console.WriteLine("   Class members: {0}, {1}",
             Employee2.name, Employee2.id);
   }
}
/*
Output:
Default values:
   Struct members: 0, 0
   Class members: , 0
Assigned values:
   Struct members: 10, 20
   Class members: Cristina Potra, 1234
*/


18. 이 예제에서 문자열의 기본값은 null입니다.

19. 따라서 값이 표시되지 않습니다.





new 한정자


1. 선언 한정자(declaration modifier) 사용되는 new 키워드는 기본 클래스에서 상속된 멤버를 명시적으로 숨깁니다.

2. 상속된 멤버를 숨기면 파생 버전의 멤버로 기본 클래스 버전의 멤버를 대신하게 됩니다.

3. new 한정자를 사용하지 않고 멤버를 숨길 수도 있지만 컴파일러 경고가 발생합니다.

4. new를 사용하여 멤버를 명시적으로 숨기면 이 경고가 발생하지 않습니다(suppress).

5. 상속된 멤버(an inherited member)를 숨기려면, 멤버 이름을 사용하여 파생된 클래스에 해당 멤버를 선언한 다음 new 키워드를 사용하여 이를 한정합니다.


public class BaseC
{
    public int x;
    public void Invoke() { }
}
public class DerivedC : BaseC
{
    new public void Invoke() { }
}


6. 이 예제에서 BaseC.Invoke는 DerivedC.Invoke에 의해 숨겨집니다.

7. x 필드는 비슷한 이름으로 숨겨져 있지 않기 때문에 영향을 받지 않습니다.

8. 상속(inheritance)을 사용한 이름 숨기기는 다음 중 한 가지 형식을 취합니다(take).

    1) 일반적으로 클래스 또는 구조체에 파생된 상수 필드, 속성 또는 형식은 동일한 이름의 모든 기본 클래스 멤버를 숨깁니다.

        이 사항이 적용되지 않는 경우가 있습니다.

        예를 들어 호출할 수 없는 형식이 포함된 N이라는 이름의 새 필드를 선언하고 기본 형식에서 N을 메서드로 선언하면 새 필드가 호출 구문에서(in invocation syntax) 기본 선언을 숨기지 않습니다.

       자세한 내용은 C# 언어 사양(C# language specification)("식" 단원의 "멤버 조회(Member Lookup)" 단원 참조)을 참조하세요.

    2) 클래스 또는 구조체에 파생된 메서드는 기본 클래스에서 동일한 이름의 속성, 필드 및 형식을 숨깁니다.

       또한 시그니처가 동일한 기본 클래스 메서드도 모두 숨깁니다.

    3) 클래스 또는 구조체에 파생된 인덱서는 시그니처가 동일한 기본 클래스 인덱서를 모두 숨깁니다.

9. 동일한 멤버에 대해 new와 override를 모두 사용하면 오류가 발생합니다.

10. 두 한정자는 함께 사용할 수 없는 의미(mutually exclusive meanings)를 지니고 있기 때문입니다.

11. new 한정자는 동일한 이름의 새 멤버를 만들고 원래 멤버를 숨깁니다.

12. override 한정자는 상속된 멤버에 대한 구현을 확장(extends the implementation)합니다.

13. 상속된 멤버를 숨기지 않는 선언에 new 한정자를 사용하면 경고가 발생합니다.

14. 이 예제에서 기본 클래스 BaseC 및 파생 클래스 DerivedC는 동일한 필드 이름 x를 사용하므로 상속된 필드의 값이 숨겨집니다.

15. 이 예제에서는 new 한정자의 사용법을 보여 줍니다.

16. 또한 정규화된 이름(fully qualified names)을 사용하여 기본 클래스의 숨겨진 멤버에 액세스하는 방법을 보여 줍니다.


public class BaseC
{
    public static int x = 55;
    public static int y = 22;
}

public class DerivedC : BaseC
{
    // Hide field 'x'.
    new public static int x = 100;

    static void Main()
    {
        // Display the new value of x:
        Console.WriteLine(x);

        // Display the hidden value of x:
        Console.WriteLine(BaseC.x);

        // Display the unhidden member y:
        Console.WriteLine(y);
    }
}
/*
Output:
100
55
22
*/


17. 이 예제에서 중첩 클래스는 기본 클래스에서 이름이 동일한 클래스를 숨깁니다.

18. 이 예제에서는 new 한정자를 사용하여 경고 메시지를 제거하는 방법과 정규화된 이름을 사용하여 숨겨진 클래스 멤버에 액세스하는 방법을 보여 줍니다.


public class BaseC 
{
    public class NestedC 
    {
        public int x = 200;
        public int y;
    }
}

public class DerivedC : BaseC 
{
    // Nested type hiding the base type members.
    new public class NestedC   
    {
        public int x = 100;
        public int y; 
        public int z;
    }

    static void Main() 
    {
        // Creating an object from the overlapping class:
        NestedC c1  = new NestedC();

        // Creating an object from the hidden class:
        BaseC.NestedC c2 = new BaseC.NestedC();

        Console.WriteLine(c1.x);
        Console.WriteLine(c2.x);   
    }
}
/*
Output:
100
200
*/


19. new 한정자를 제거해도 프로그램은 컴파일되고 실행되지만 다음과 같은 경고가 발생합니다.


The keyword new is required on 'MyDerivedC.x' because it hides inherited member 'MyBaseC.x'.





new 제약 조건


1. new 제약 조건(constraint)은 제네릭 클래스 선언의 모든 형식 인수가 매개 변수 없는 public 생성자(a public parameterless constructor)를 갖도록 지정합니다.

2. new 제약 조건을 사용하려면 형식이 abstract일 수 없습니다.

3. 다음 예제에서와 같이 제네릭 클래스로 형식의 새 인스턴스를 만들 때 형식 매개 변수에 new 제약 조건을 적용합니다.


class ItemFactory<T> where T : new()
{
    public T GetNewItem()
    {
        return new T();
    }
}

4. 다른 제약 조건과 함께 new() 제약 조건을 사용하는 경우 이 제약 조건은 마지막에 지정해야 합니다.


public class ItemFactory2<T>
    where T : IComparable, new()
{
}

5. 자세한 내용은 형식 매개 변수에 대한 제약 조건을 참조하십시오.





null


1. null 키워드는 아무 개체도 참조하지 않는 null 참조를 나타내는 리터럴입니다.

2. null은 참조 형식 변수의 기본값입니다.

3. 일반 값 형식(Ordinary value types)은 null일 수 없습니다.

4. 하지만(however), C# 2.0에는 nullable 값 형식이 도입되었습니다.

5. 자세한 내용은 nullable 형식을 참조하십시오.

6. 다음 예제에서는 null 키워드의 몇 가지 동작(some behaviors)을 보여줍니다.



class Program
{
    class MyClass
    {
        public void MyMethod() { }
    }

    static void Main(string[] args)
    {
        // Set a breakpoint here to see that mc = null.
        // However, the compiler considers it "unassigned."
        // and generates a compiler error if you try to
        // use the variable.
        MyClass mc;

        // Now the variable can be used, but...
        mc = null;

        // ... a method call on a null object raises 
        // a run-time NullReferenceException.
        // Uncomment the following line to see for yourself.
        // mc.MyMethod();

        // Now mc has a value.
        mc = new MyClass();

        // You can call its method.
        mc.MyMethod();

        // Set mc to null again. The object it referenced
        // is no longer accessible and can now be garbage-collected.
        mc = null;

        // A null string is not the same as an empty string.
        string s = null;
        string t = String.Empty; // Logically the same as ""

        // Equals applied to any null object returns false.
        bool b = (t.Equals(s));
        Console.WriteLine(b);

        // Equality operator also returns false when one
        // operand is null.
        Console.WriteLine("Empty string {0} null string", s == t ? "equals": "does not equal");

        // Returns true.
        Console.WriteLine("null == null is {0}", null == null);


        // A value type cannot be null
        // int i = null; // Compiler error!

        // Use a nullable value type instead:
        int? i = null;

        // Keep the console window open in debug mode.
        System.Console.WriteLine("Press any key to exit.");
        System.Console.ReadKey();

    }
}


'프로그래밍 > C#' 카테고리의 다른 글

C# 키워드 T~Z  (0) 2016.06.03
C# 키워드 O~S  (0) 2016.05.31
C# 키워드 A-E  (0) 2016.05.13
연산자 2  (0) 2016.05.10
C# 총정리  (0) 2016.04.19
:
Posted by 지훈2