1. Deterministic Object Cleanup

- 자원 반납을 제어하기 위해서, C#에서는 Dispose() 메소드를 가지고 있는 System.IDisposable 인터페이스를 제공한다.
- Dispose() 메소드로 자원 해제를 관리하려면, GC.SuppressFinalize(this); 이렇게 GC 클래스의 SuppressFinalize 메소드를 Dispose() 메소드 내에서 호출해 준다.
- C# also has some syntactic sugar via the using keyword that makes releasing the resources used by classes occur in a more deterministic manner via the Dispose method.
- using은 뭐야.. ㅠ.ㅠ;; 어렵군.

2. Delegates

- 메소드 포인터를 넘겨준다. 콜백 함수를 제공하기 위한 매카니즘.
- 이벤트 핸들러 등록할 때 사용.
- (스트레티지 패턴과 관련이 있을까..?)
- 만드는 순서
    - 콜백 함수로 호출되기 원하는 메소드의 파라미터와 리턴타입을 가진 delegate를 선언한다.

public delegate Mammal CallbackFunction(Dog d);

    - deletege를 파라미터로 받는 메소드를 정의한다.

    //create delegate using delegate object (old way)
    CallbackFunction myCallback = new CallbackFunction(BarkAndReturnHome);
    myCallback(dog);

    //create delegate using delegate inference (new way)
    CallbackFunction myCallback2 = BarkAndScareCat;
    myCallback2(dog);

    - 이제 delegate와 같은 메소드 시그너쳐를 가졌거나 covariant 리턴타입과 covariant 파라미터를 가진 메소드를 가지고 delegate의 인스턴스를 만들 수 있다. 그리고 이 녀석을 위에서 만든 delegate를 파라미터로 받는 메소드에 넘겨줄 수 있다.

public static Cat BarkAndScareCat(Dog d)
    {
    d.Speak();
    Cat c = new Cat();
    c.Speak();
    return c;
    }

- the same delegate can refer to static and instance
methods, even at the same time, since delegates are multicast.(먼소린지..)

3. Value Types (Structs)

- 스택에 객체가 살도록 할 수 있는데, int 같은 타입들이 그렇게 구현되어 있다.
- Value Type 들은 항상 값으로 전달되고, GC의 대상이 되지 않는다.
- Value Type의 배열은 레퍼런스가 아니라 실제 Value를 가지고 있다.
- class가 아니라 struct로 선언한다.
- 다른 생성자를 만들어도, 기본 생성자를 자동으로 만들어 주네;; 참조한 문서에서는 기본 생성자로 생성할 수 없다고 나와있었는데.. 흠..

4. Run Time Type Identification (as operator)

- 타입 캐스팅 할 때는 as 연산자를 사용할 수 있다.
- Value Type에는 사용할 수 없다.
- MyClass mc = o as MyClass;
- 캐스팅이 적절하지 않으면, null이 된다.

5. Properties

- 자바의 getter, setter 처럼 필드에 간접적으로 접근하도록 하는것이 가능하다.

    private string name;

    //property with public getter and private setter
    public string Name{

    get{
        return name;
    }  

    private set {
        name = value;
    }
    }

- 값 설정하기

User.MinimumAge = -5;

- 값 가져오기

Console.WriteLine(User.MinimunAge);

6. Multidimensional Arrays

- multidementional 배열과 jagged 배열을 구분한다.
- multidementional 배열은 모두 같은 길이의 배열을 가진 배열.
- jagged 배열은 다른 길이의 배열들을 가진 배열.

7. Indexers

- [ ] 를 재정의 하기 위한 특별한 문법.
- 아음.. pass

8. Preprocessor Directives

- C/C++에 있는 것중에 몇개만 남겨놨음.
- The primary functionality that remains is the ability to  #define and #undef identifiers and also the ability to select which sections of code to compile based on the validity of certain expressions via #if, #elif, and #else.
- #error: 컴파일 할 때 이 뒤에 적어준 메시지 출력하면서 에러 발생.
- #warning: 컴파일 할 때 이 뒤에 적어준 메시지 출력하면서 경고 발생.
- #pragma: 컴파일 경고 무시 해줌.
- #line: 컴파일 에러 발견했을 때 소스 라인 알려주고 싶을 때 사용.

9. Aliases

- C/C++의 typedef 처럼 풀 패키지 경로를 가진 클래스의 별칭을 만들 때 using 사용.
- 다른 네임스페이스 존재하는 같은 클래스 이름을 가진 클래스들을 지칭할 때 이용 하겠군.
using Terminal = System.Console;

10. Runtime Code Generation

- 자바에서 런타임에 바이트코드를 생성해서 로딩할 수 있는 것처럼 C#에서는 Reflection.Emit 네임스페이스에 들어있는 녀석들을 사용해서 그런 걸 할 수 있다.

11. Pointers and Unsafe Code

- 포인터를 사용하는 블럭을 지정할 수 있다.
- unsafe 키워드로 블럭을 지정하고 컴파일 할 때 /unsafe 옵션을 준다.
- GC가 변수의 메모리 위치를 런타임 중에 변경할 수 있기 때문에, 포인터를 쓰려면 fixed 키워드로 메모리 위치를 런타임에 변경하지 않도록 설정해야 한다.
- 왜 포인터를 쓰고 싶을까?

12. Pass by Reference

- 자바는 전부 Pass by value
- C#에서는 Reference도 넘길 수 있다. 메소드 파라미터에 ref나 out 키워드를 사용한다. ref 키워드를 사용할 떄는 반드시 초기화가 된 상태여야 한다.

13. Verbatim Strings

- 문자열 앞에 @를 붙여서 \도 그냥 문자로 인식하게 할 수 있다.
string filename2 =  "C:\\My Documents\\My Files\\File.html"; // 대신에
string filename  = @"C:\My Documents\My Files\File.html";  //요렇게

14. Overflow Detection

- 변수 타입 변환 할 때, 큰녀석을 작은 그릇에 넣을 때 오버플로우가 발생할 수 있는데, 이 예외를 평상시엔 무시하다가 컴파일 옵션으로 /checked+ 이걸 주면 그 때는 예외 발생시켜준다.
- checked 블럭을 사용해서 항상 이 예외를 잡도록 할 수도 있다.
- unchecked 블럭을 사용해서 항상 이 예외를 무시하도록 할 수 있다.

15. Explicit Interface Implementation

- 같은 이름의 메소드를 가지고 있는 두 개의 인터페이스를 구현할 때 자바는 그냥 하나의 메소드를 구현하는 수밖에 없다.
- C#은 각각의 인터페이스 구현체에 해당하는 메소드를 구현할 수 있다. 메소드 이름앞에 인터페이스이름. 을 붙여준다.
- 사용할 때는 대신 타입을 해당 타입으로 캐스팅 한 다음에 써야 한다. 인터페이스를 구현한 클래스 타입으로 쓰면 안 된다.(에러다.)

16. Friend Assemblies

- 해당 assmbly를 다른 assembly에 노출 시킬 수 있다. [assembly:InternalsVisibleTo("friend_assembly_test_2")]
- internal 변수는 assembly에서 바로 접근할 수 있다.
Console.WriteLine(f2.secret);

17. The Namespace Qualifier

- 네임스페이스의 충돌을 방지하기 위해서 :: 의 왼쪽에는 스콥, 오른쪽에는 네임스페이스로 구분할 수 있다.
global::System.Console.WriteLine("The time is " + Console);

18. Iterators (Continuations)

- foreach 루프로 돌리려면 in 다음에 오는 녀석이 System.Collections.IEnumerable 타입이어야 한다.
- yield를 사용하면, 특정 메소드나 프로퍼티를 iterator로 변환해 준다.
- yield return를 사용해서 하나씩 넘겨줄 수도 있다.
- 여러 콜렉션을 이터레이트 하고 싶은 때 사용하면 되겠군.

19. Partial Types

- 클래스 하나, Struct 하나, 인터페이스 하나를 여러 파일에 걸쳐서 작성하는 것이 가능하다.
- partial 키워드를 class앞에 사용한다.
- 하나의 파일에서는 private으로 하고 하나의 파일에서는 public으로 하는 것은 안된다.

20. Static Classes

- 정적인 클래스를 만들 수 있는데, 이 녀석은 base 클래스가 될 수도 없고, 인스턴스 멤버를 가질 수도 없다.
-static 키워드를 class 앞에 붙여준다.
- 유틸 클래스 만들 때 쓰나보다.

21. Nullable Types

- System.Nullable 타입의 객체는 null 될 수 있다.
- Value Type 들도 변수 선언할 때 타입 뒤에 ?를 붙여 주면 null 값을 가질 수 있다.
int? x = 5;  // Nullable<int> 와 동일.
- ?? 연산자는 해당 value type이 null 일 때 오른쪽에 있는 인자의 값을 왼쪽의 변수에 대입한다.
x ?? y; // x == (null ? y : x);

22. Anonymous Methods

- delegate에 넘겨줄 콜백 메소드 인스턴스를 마치 Java에서 anonymous class 정의하듯이 메소드 이름이 들어갈 위치에 메소드를 구현하는 기법.

    /* anonymous code block */
    CallbackFunction cf = delegate (string a, int b){
                             for(int i = 0; i < b ; i++)
                               Console.WriteLine("{0}.) {1}", i + 1, a); };

- goto, break, continue 키워드를 사용해서 anonymous method 경계를 넘나들면 안 된다.
- ref, out 파라미터로 anonymous method 경계 밖에 있는 녀석들을 받아오면 안 된다.