posted by 방랑군 2009. 10. 7. 11:24

참조 : http://dalbong2.net/entry/C-20-iterators
         http://www.hoons.kr/board.aspx?Name=cshaptip&BoardIdx=1021&Page=1&Mode=2

1. Iterators

using System; 
using System.Collections.Generic; 
class Test 

  public static void Main() 
  { 
       foreach (string s in GetItems()) 
           Console.WriteLine(s); 
  }

  private static IEnumerable GetItems() 
  { 
       yield return "Hello yield 1"; 
       yield return "Hello yield 2"; 
       yield return "Hello yield 3"; 
       yield return "Hello yield 4"; 
       yield return "Hello yield 5"; 
  } 


"yield return" 문이 있는데, iteration의 다음 값을 반환한다고 한다. 
"yield break" 문도 있단다. 

『The yield return statement produces the next value of the iteration. 
  The yield break statement indicates that the iteration is complete.』 

GetItems() 메소드의 리턴 타입이 IEnumerable 이라는 것도 주목할 부분이다. 


참조 문서 
c# 2.0 iterators - 
http://community.bartdesmet.net/blogs/bart/archive/2006/07/06/4121.aspx

2. Partial

// MyForms1.cs
partial public class MyForms
{
  public BusinessLogic(){}

// MyForms2.cs
partial public class MyForms
{
  public PresentationLogic(){}
}

Partial 클래스는 하나의 클래스를 여러 개의 파일로 나누어 작성할 수 있는 기능이다. 이 기능은 Windows Forms이나 Web 응용 프로그램을 협업으로 개발해 왔다면 가장 크게 매력을 느낄 것이다. Partial 클래스를 이용하면 한 클래스를 여러 가지 로직(비즈니스 로직과 프리젠테이션 로직)으로 나누어 개발할 수 있다. 물론 각 로직을 각각의 클래스로 구현하는 것이 바람직했지만, Forms 클래스는 어쩔 수 없이 여러 로직이 공존할 수 밖에 없는 경우가 많았다(특히 프리젠테이션 로직은 자동으로 생성되는 코드가 대부분이다). 비단 그러한 문제가 아니더라도 여러 명의 개발자가 자신이 맡은 메쏘드를 나누어서 개발할 수 있다면, 이보다 더 좋은 협업 방법이 없을 것이다. 이는 형상 관리 측면에서도 큰 이점을 제공한다.

Partial 클래스는 기존의 클래스 앞에 partial 키워드를 추가하여 작성할 수 있다. 물론, partial 키워드를 사용한 클래스는 여러 파일에 나뉘어 존재할 수 있다.
위 소스의 MyForms 클래스는 비즈니스 로직을 구현한 MyForms1.cs 파일과 프리젠테이션 로직을 구현한 MyForms2.cs 파일로 나뉘어져 있다. 컴파일러는 이와 같이 나뉘어져 있는 파일을 조합하여 하나의 MyForms 클래스를 작성한다.

Partial 클래스를 작성할 때 다음과 같은 사항을 유의해야 한다.

1. Partial 클래스는 동일한 어셈블리/모듈(dll 또는 exe)에 존재해야 한다.
2. 한번이라도 partial로 선언된 클래스는 모두 동일하게 partial로 선언되어야 한다.

partial public class MyForms {}

public class MyForms {} // 컴파일 오류

3. Generic으로 사용될 매개 변수들이 일치해야 한다.
4. public/private/protected/internal 등을 사용할 수 있다.
5. 중첩된 클래스에 대해서도 Partial 클래스를 작성할 수 있다.
6. Partial 클래스에 적용된 특성(Attribute)들은 컴파일 시에 모두 병합된다.

3. Nullable
 만약 값 타입과 참조 타입의 큰 차이점이 무엇이냐고 묻는다면, 널(null) 값을 설정할 수 있는지의 여부일 것이다. 참조 타입은 널 값을 설정할 수 있는 반면 값 타입은 불가능하다. 이는 값 타입 입장에서 보면, 상당히 불합리한 처우가 아닐 수 없다. 왜 값 타입은 언제나 초기화가 필요한 것일까? 참조 타입은 널 값을 설정함으로써 구체적으로 객체를 생성하는 것을 뒤로 미룰 수 있지만, 값 타입은 변수를 선언함과 동시에 개발자가 원하든 원하지 않든 간에 어떤 값으로 설정되기 때문에 개발자가 할 수 있는 일이라곤 0이나 -1을 널 대신 사용하는 정도이다. 0과 -1이 해당 변수에서 특별한 의미를 지니고 있다면, 그나마도 불가능하다.

Nullable 타입은 기본 타입에 물음표(?)를 추가하여 선언한다. 예를 들어, int?와 같이 선언하면 기본 타입인 int의 Nullable 타입이 선언된다. 이 때 선언된 타입은 널인지에 대한 여부를 확인할 수 있는 기능을 지원한다는 점을 제외하면 내부적으로 기본 타입(int 형)과 동일하다. 이와 같은 기능이 가능한 이유는 바로 Generic 덕분이다.

 <리스트 3> Nullable 타입의 예

int? x;
if (x != null)
  Console.WriteLine(x.Value);
else
  Console.WriteLine("Null");

C# 언어 스펙을 보면 Nullable 타입은 다음 <리스트 4>와 같이 HasValue와 Value 속성을 노출하는 Generic 구조체이다. 이때 HasValue가 false이면 널인 경우이고 HasValue가 false일 때, Value 속성 값을 설정하면 System.InvalidOperationException 예외가 발생하도록 구현되어 있다.

 <리스트 4> Nullable Generic 클래스의 기본 구조

public struct Nullable where A : struct {
  bool HasValue { get; }
  A Value { get; }

  public Nullable(A value);
}

따라서 int? x = 123; 과 같은 코드를 작성하면 컴파일러는 Nullable x = new Nullable(123); 을 생성한다.

지금까지 Nullable 타입에 대해서 간단하게 살펴보았는데, Nullable 타입은 탄생 배경부터 여러 가지 이슈들을 동반하고 있다(예를 들면, int?와 int??의 사용). 따라서 Nullable 타입에 관한 보다 자세한 정보는 MSDN의 블로그를 통해서 확인하도록 한다.@




'IT > C#' 카테고리의 다른 글

닷넷 트랜잭션 정리  (0) 2009.09.30
C#2.0 , C# 3.0 New Features  (0) 2009.09.15
C# 3.0 개요  (0) 2009.09.11
[C# 2.0] Generics, Iterator, Anonymous, Partial  (0) 2009.08.24
[.net Framework] System.Activator 객체  (0) 2009.08.24