C# 2.0

Part 3/¶ C#(C sharp) 2018. 9. 14. 23:50

C#의 역사 : https://docs.microsoft.com/ko-kr/dotnet/csharp/whats-new/csharp-version-history


제네릭(Generic)https://docs.microsoft.com/ko-kr/dotnet/csharp/programming-guide/generics/

제네릭이 C# 언어 및 CLR(공용 언어 런타임)의 버전 2.0에 추가되었습니다. 제네릭은 .NET Framework에 클라이언트 코드에서 클래스 또는 메서드를 선언하고 인스턴스화할 때까지 하나 이상의 형식 사양을 따르는 클래스 및 메서드를 디자인할 수 있도록 만드는 형식 매개 변수 개념을 도입합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// Declare the generic class.
public class GenericList<T> {
    public void Add(T input) { }
}
 
class TestGenericList {
    private class ExampleClass { }
    static void Main() {
 
        // Declare a list of type int.
        GenericList<int> list1 = new GenericList<int>();
        list1.Add(1);
 
        // Declare a list of type string.
        GenericList<string> list2 = new GenericList<string>();
        list2.Add("");
 
        // Declare a list of type ExampleClass.
        GenericList<ExampleClass> list3 = new GenericList<ExampleClass>();
        list3.Add(new ExampleClass());
    }
}
cs

.NET 클래스 라이브러리의 ArrayList 컬렉션 클래스를 사용하는 간단한 프로그램을 작성하면 제네릭이 아닌 컬렉션 클래스를 사용할 경우의 제한 사항을 보여 줄 수 있습니다. ArrayList 클래스의 인스턴스는 모든 참조 또는 값 형식을 저장할 수 있습니다.

ArrayList에 추가된 모든 참조 형식이나 값 형식이 암시적으로 Object로 업캐스팅됩니다. 캐스팅과 boxing 및 unboxing 작업은 모두 성능을 저하시키므로 큰 컬렉션을 반복해야 하는 시나리오에서는 boxing 및 unboxing이 큰 영향을 줄 수 있습니다. 다른 제한 사항은 컴파일 시간 형식 검사가 없다는 것입니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
System.Collections.ArrayList list = new System.Collections.ArrayList();

// Add an integer to the list.
list.Add(3);

// Add a string to the list. This will compile, but may cause an error later.
list.Add("It is raining in Redmond.");
 
int t = 0;

// This causes an InvalidCastException to be returned.
foreach (int x in list) {
    t += x;
}
cs



?? 연산자 (null 병합 연산자) :  https://docs.microsoft.com/ko-kr/dotnet/csharp/language-reference/operators/null-coalescing-operator

?? 연산자는 null 병합 연산자라고 합니다. 이 연산자는 피연산자가 null이 아닐 경우 왼쪽 피연산자를 반환하고 null일 경우 오른쪽 피연산자를 반환합니다.

nullable 형식 : https://docs.microsoft.com/ko-kr/dotnet/csharp/programming-guide/nullable-types/

기본 형식의 정의되지 않은 값을 표시해야 하는 경우 nullable 형식을 사용합니다.
nullable 형식은 null 값이 할당될 수 있는 값-형식 변수를 나타냅니다.
T? 구문은 Nullable<T>의 축약형입니다.
Nullable<T>.HasValue 및 Nullable<T>.Value 읽기 전용 속성을 사용하여 null인지 테스트하고 값을 검색합니다.
- HasValue 속성은 변수에 값이 있으면 true를 반환하고, null이면 false를 반환합니다.
- Value 속성은 HasValue가 true를 반환하는 경우 값을 반환합니다. 그렇지 않으면 InvalidOperationException이 throw됩니다.

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
class NullCoalesce {
    static int? GetNullableInt() {
        return null;
    }
 
    static string GetStringValue() {
        return null;
    }
 
    static void Main() {
 
        //Nullable<int> x = null;
        int? x = null;
 
        // x의 값이 null이 아닌 경우, y는 x값을 가진다. null인 경우 -1을 지정
        // if ( x == null ) { y = -1; } else { y = x; }
        int y = x ?? -1;
 
        // 메소드의 결과가 null인 경우 default(int)를 가지고,
        // null이 아닌 경우 메소드의 결과 i 값으로 
        int i = GetNullableInt() ?? default(int);
 
        string s = GetStringValue();
        // s의 값을 출력, s의 값이 null인 경우 "Unspecified"를 출력
        // 이 예제에서는 "Unspecified"가 출력
        Console.WriteLine(s ?? "Unspecified");
    }
}
cs



default 키워드(기본값 식)https://docs.microsoft.com/ko-kr/dotnet/csharp/programming-guide/statements-expressions-operators/default-value-expressions

기본값 식은 특히 제네릭 클래스와 메서드에서 유용합니다. 제네릭 사용으로 발생하는 한 가지 문제는 다음과 같은 내용을 미리 알지 못하는 경우 매개 변수가 있는 형식 T에 기본값을 할당하는 방법입니다.
- T가 참조 형식인지 값 형식인지 여부
- T이 값 형식인 경우 숫자 값인지 구조체인지 여부를 표시합니다.

매개 변수가 있는 형식 T의 변수 t가 제공되었을 때 t = null 문은 T가 참조 형식인 경우에만 유효합니다. 할당 t = 0은 숫자 값 형식에만 작동하고 구조체에는 작동하지 않습니다. 이를 해결하려면 기본값 식을 사용합니다.

1
2
3
4
5
6
7
T t = default(T);
 
// 제네릭 클래스와 메서드 이외에도 사용이 가능
var s = default(string);
var d = default(dynamic);
var i = default(int);
var n = default(int?); // n is a Nullable int where HasValue is false.
cs



yield return/break(반복기) : https://docs.microsoft.com/ko-kr/dotnet/csharp/language-reference/keywords/yieldhttps://docs.microsoft.com/ko-kr/dotnet/csharp/iterators

yield return 문을 사용하여 각 요소를 따로따로 반환할 수 있습니다.
yield break 문을 사용하여 반복기를 종료할 수 있습니다.

foreach 문 또는 LINQ 쿼리를 이용하여 반복기 메서드를 사용합니다. 각각의 foreach 루프의 반복이 반복기 메서드를 호출합니다. yield return 문이 반복기 메서드에 도달하면 expression 이 반환되고 코드에서 현재 위치는 유지됩니다. 다음에 반복기 함수가 호출되면 해당 위치에서 실행이 다시 시작됩니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
using System.Collections.Generic;
 
public class PowersOf2 {
    static void Main() {
        // 2의 8승까지 출력한다.
        foreach (int i in Power(28))
        {
            Console.Write("{0} ", i);
        }
    }
 
    public static IEnumerable<int> Power(int number, int exponent) {
        int result = 1;
 
        for (int i = 0; i < exponent; i++)
        {
            result = result * number;
            yield return result;
        }
    }
 
    // 출력결과: 2 4 8 16 32 64 128 256
}
cs



Partial 클래스https://docs.microsoft.com/ko-kr/dotnet/csharp/programming-guide/classes-and-structs/partial-classes-and-methods

클래스, 구조체, 인터페이스 또는 메서드의 정의를 둘 이상의 소스 파일에 분할할 수 있습니다. 각 소스 파일에는 형식 또는 메서드 정의 섹션이 있으며 모든 부분은 응용 프로그램이 컴파일될 때 결합됩니다.
(C# 3.0에서 partial 메소드가 추가됨)

1
2
3
4
5
6
7
8
9
10
11
public partial class Employee {
    public void DoWork() {
    
    }
}
 
public partial class Employee {
    public void GoToLunch() {
 
    }
}
cs



무명 메서드 : https://docs.microsoft.com/ko-kr/dotnet/csharp/programming-guide/statements-expressions-operators/anonymous-methods

이름이 없는 메서드로 델리게이트에 전달되는 메소드가 일회성으로만 필요할 때 편의상 사용된다.
무명 메서드를 사용하면 별도 메서드를 만들 필요가 없기 때문에 대리자를 인스턴스화하는 코딩 오버헤드가 줄어듭니다.

1
2
3
4
// Create a delegate.
delegate void Del(int x);
// Instantiate the delegate using an anonymous method.
Del d = delegate(int k) { /* ... */ };
cs

1
2
3
// Create a handler for a click event.
button1.Click += delegate(System.Object o, System.EventArgs e)
                   { System.Windows.Forms.MessageBox.Show("Click!"); };
cs

메서드를 만드는 것이 불필요한 오버헤드처럼 보일 수도 있는 경우 대리자 대신 코드 블록을 지정하는 것이 유용할 수 있습니다. 좋은 예로 새 스레드를 시작하는 경우를 들 수 있습니다. 이 클래스는 스레드를 만들며, 대리자에 대한 추가 메서드를 만들지 않고 스레드에서 실행하는 코드도 포함합니다.

1
2
3
4
5
6
7
8
void StartThread() {
    System.Threading.Thread t1 = new System.Threading.Thread
      ( delegate() {
                System.Console.Write("Hello, ");
                System.Console.WriteLine("World!");
            });
    t1.Start();
}
cs



정적 클래스https://docs.microsoft.com/ko-kr/dotnet/csharp/programming-guide/classes-and-structs/static-classes-and-static-class-members

정적 클래스는 기본적으로 비정적 클래스와 동일하지만, 정적 클래스는 인스턴스화할 수 없다는 한 가지 차이점이 있습니다. 즉, new 키워드를 사용하여 클래스 형식의 변수를 만들 수 없습니다. 인스턴스 변수가 없기 때문에 클래스 이름 자체를 사용하여 정적 클래스의 멤버에 액세스합니다.

※ 자체 인스턴스 하나만 생성될 수 있도록 하는 비정적 클래스를 만들려면 C#에서 Singleton 키워드로 구현을 참조하세요.

'Part 3 > ¶ C#(C sharp)' 카테고리의 다른 글

UI 접근  (0) 2020.03.15
Event 처리  (0) 2020.03.08
C# 버전 특징  (0) 2018.09.14
AND