Tag Archives: 프로그래밍

C# 6.0 완벽 가이드/ 객체 처분과 쓰레기 수거

  • 객체 중에는 열린 파일이나 자물쇠(lock), 운영체제 핸들, 비관리(unmanaged) 객체 같은 자원들을 해제하는 명시적인 해체(tear-down) 코드가 필요한 객체들이 있다. .NET의 어법에서 그런 작업을 처분(disposal)이라고 부른다.
    • .NET Framework는 객체 처분 기능을 지원하기 위해 IDisposable이라는 인터페이스를 제공한다.
  • 처분은 쓰레기 수거(garbage collection, GC)와는 다른 연산이다. 보통의 경우 처분은 프로그래머가 명시적으로 수행하지만, 쓰레기 수거는 런타임이 자동으로 수행해준다.
    • 다른 말로 하면 프로그래머는 파일 핸들이나 자물쇠, 운영체제 자원들의 해제를 신경 쓰고, CLR은 그런 자원들이 차지하던 메모리의 해제를 신경 쓴다.

IDisposable, Dispose, Close

  • .NET Framework는 해체 수단이 필요한 형식을 위해 다음과 같은 특별한 인터페이스를 제공한다.
public interface IDisposable
{
  void Dispose();
}

Continue reading

C# 6.0 완벽 가이드/ 그 밖의 XML 기술들

XmlReader 클래스

  • XmlReader는 XML 스트림을 저수준, 전진 전용 방식으로 읽어들이는 고성능 XML 판독기를 나타내는 클래스이다.
  • XML 판독기는 XmlReader.Create를 호출해서 생성하는데, 이 메서드는 Stream이나 TextReader 또는 파일 이름을 뜻하는 URI 문자열을 인수로 받는다.
using (XmlReader reader = XmlReader.Create("customer.xml"))
  • Stream과 URI에서 XML 자료를 가져오는 속도가 느릴 수도 있기 때문에, XmlReader의 메서드들에는 비차단(nonblocking) 코드를 작성하는데 적합한 비동기 버전들이 존재한다.
  • 다음은 문자열로부터 XML을 읽어 들이는 XmlReader 인스턴스를 생성하는 예이다.
XmlReader reader = XmlReader.Create(new System.IO.StringReader(myString));

Continue reading

C# 6.0 완벽 가이드/ LINQ to XML

  • .NET Famework는 XML 자료를 다루는 여러 API를 제공한다. .NET Framework 3.5부터 범용 XML 문서 처리의 주된 수단은 LINQ to XML 이다. LINQ to XML은 가볍고 LINQ 친화적인 DOM과 이를 보충하는 일단의 질의 연산자들로 구성되어 있다.
  • LINQ to XML의 모든 형식은 System.Xml.Linq 이름공간에 있다.

전체적인 구조

DOM이란 무엇인가?

  • 다음과 같은 XML 파일을 생각해 보자
<?xml version="1.0" encoding="utf-8"?>
<customer id="123" status="archived">
  <firstname>Joe</firstname>
  <lastname>Bloggs<lastname>
</customer>
  • 다른 모든 XML 파이렃럼 이 파일은 하나의 XML 선언(declaration)으로 시작한다.
    • 그 다음은 XML 문서 전체의 뿌리(루트)에 해당하는 요소(element)로 그 이름은 customer이다.
    • 이 customer 요소에는 2개의 특성(attribute)이 있다. 각 특성은 이름(id와 status)과 값(“123”, “archived”)으로 구성된다.
    • customer 요소 안에는 두 자식 요소 firstname과 lastname이 있다. 이 요소들은 각자 단순 텍스트 내용(“Joe”와 “Bloggs”)을 담고 있다.
  • 이러한 구성요소들(선언, 요소, 특성, 값, 텍스트 내용)을 각각 클래스로 나타낼 수 있다.
    • 그리고 그런 클래스에 자식 내용을 저장할 수 있는 컬렉션 속성들을 부여한다면, 문서 전체를 나타내는 객체들의 트리를 형성할 수 있다.
    • 그러한 트리가 바로 흔히 DOM이라고 줄여서 표기하는 문서 객체 모형(document object model)이다.

Continue reading

C# 6.0 완벽 가이드/ LINQ 질의 연산자

개요

  • 표준 질의 연산자들은 다음 세 범주로 나뉜다.
    • 순차열을 입력받고 순차열을 출력하는 연산자(순차열 -> 순차열)
    • 순차열을 입력받고 요소 하나 또는 스칼라값 하나늘 출력하는 연산자
    • 입력 없이 순차열을 출력하는 연산자(생성 메서드)

순차열->순차열

  • 이 범주의 질의 연산자는 하나 이상의 순차열을 입력받고 하나의 순차열을 산출한다. 대부분의 질의 연산자가 이 범주에 속한다. 아래 그림은 이 범주의 질의 연산자 중 순차열의 형태를 바꾸는 것들을 나타낸 것이다.

분류 형식 내용 연산자
필터링(선별) IEnumerable<TSource> -> IEnumerable<TSource> 원래 요소들의 부분집합을 출력한다. Where, Take, TakeWhile, Skip, SkipWhile, Distinct
투영 IEnumerable<TSource> -> IEnumerable<TResult> 주어진 람다 함수를 이용해서 각 요소를 변환한다. SelectMany는 중첩된 순차열을 평평한 순차열로 만든다(평탄화).

LINQ to SQL이나 EF에 대한 Select와 SelectMany는 내부 결합(inner join), 왼쪽 외부 결합(left outer join), 교차 결합(cross join), 비등가 결합(non-equi join)을 수행한다.

Select, SelectMany
결합 IEnumerable<TOuter>, IEnumerable<TInner> -> IEnumerable<TResult>
IEnumerable<TFirst>, IEnumerable<TSecond> -> IEnumerable<TResult>
두 순차열의 요소들을 합친다. Join과 GroupJoin 연산자는 지역 질의에 효율적으로 작동하도록 설계된 것으로, 내부 결합과 왼쪽 외부 결합을 지원한다.

Zip 연산자는 두 순차열을 동시에 열거하면서 각 요소 쌍에 함수를 적용한다. Zip 연산자에서는 두 형식 매개변수의 이름이 TOuter와 TInner가 아니라 TFirst와 TSecond이다.

Join, GroupJoin, Zip
정렬 IEnumerable<TSource> -> IOrderedEnumerable<TSource> 입력 순차열 요소들의 순서를 바꾼다. OrderBy, ThenBy, Reverse
그룹화 IEnumerable<TSource> -> IEnumerable<IGrouping<TKey, TElement>> 입력 순차열의 요소들을 적절히 묶어서 여러 개의 부분 순차열들을 출력한다. GroupBy
집합 연산 IEnumerable<TSource>, IEnumerable<TSource> -> IEnumerable<TSource> 같은 형식의 순차열 두 개를 입력 받아서 합집합, 교집합, 차집합을 출력한다. Concat, Union, Intersect
변환 메서드: 가져오기 IEnumerable -> IEnumerable<TResult> OfType, Cast
변환 메서드: 내보내기 IEnumerable<TSource> -> 배열, 목록, 사전, 조회 객체(lookup), 순차열 ToArray, ToList, ToDictionary, ToLookup, AsEnumerable, AsQueryable

Continue reading

C# 6.0 완벽 가이드/ LINQ 질의

  • LINQ (Language Intergrated Query; 언어에 통합된 질의)는 지역 객체 컬렉션과 원격 자료 저장소에 대한 형식에 안전한 구조적 질의를 작성하는데 사용하는 C# 언어 기능들과 .NET Framework 기능들을 통칭하는 용어이다. LINQ는 C# 3.0과 .NET Framework 3.5에 도입되었다.
  • LINQ를 이용하면 IEnumerable<T>를 구현하는 임의의 컬렉션(목록, 배열)과 XML DOM에 대해 질의를 수행할 수 있으며, SQL Server 데이터베이스의 테이블과 같은 원격 자료 저장소에 대한 질의도 수행할 수 있다. LINQ는 컴파일 시점 형식 점검의 장점과 동적인 질의 작성의 장점을 모두 제공한다.

첫걸음

  • LINQ의 기본적인 자료 단위는 순차열(sequence)과 요소(element)이다. 순차열은 IEnumerable<T>를 구현하는 임의의 객체이고 요소는 그 순차열에 들어있는 항목이다. 다음 예에서 names는 순차열이고, “Tom”, “Dick”, “Harray”는 요소들이다.
    • 메모리 안에 있는 객체들의 지역 컬렉션이라는 점에서 이런 순차열을 지역 순차열이라고 부른다.
string[] names = { "Tom", "Dick", "Harray" };
  • 질의 연산자(query operator)는 순차열에 어떠한 변환(transformation) 연산을 적용하는 메서드이다. 전형적인 질의 연산자는 입력 순차열 하나를 받아서 출력 순차열을 산출한다. System.Linq의 Enumerable 클래스에는 약 40개의 질의 연산자가 있는데, 이들은 모두 정적 확장 메서드로 구현되어 있다. 이들을 통틀어 표준 질의 연산자라고 부른다.
    • 지역 순차열에 대해 작용하는 질의를 지역 질의(local query) 또는 객체 대상 LINQ 질의라고 부른다.
    • LINQ는 또한 SQL Server 데이터베이스 같은 원격 자료 저장소에서 동적으로 자료를 공급받는 순차열도 지원한다. 그런 순차열은 IQueryable<T> 인터페이스를 추가로 구현하는데, 이 인터페이스에 대응되는 일단의 표준 질의 연산자들이 Queryable 클래스에 있다.
  • LINQ에서 말하는 질의는 순차열들과 질의 연산자들로 이루어진 하나의 표현식이다. 그 표현식을 평가하면 순차열들이 연산자들에 의해 변환된다.
    • 예컨대 Where 연산자를 이용하면 이름들을 담은 배열에서 길이가 4개 이상인 이름만 추출할 수 있다.
string[] names = { "Tom", "Dick", "Harray" };
IEnumerable<string> filteredNames = System.Linq.Enumerable.Where(names, n => n.Length >= 4)

foreach (int n in filteredNames)
  Console.Write(n);  // Dick Harry

Continue reading

C# 6.0 완벽 가이드/ 컬렉션

  • 컬렉션에 관련된 .NET Framework의 형식들은 크게 다음 세 범주로 나뉜다.
    • 표준 컬렉션 프로토콜을 정의하는 인터페이스
    • 바로 사용할 수 있는 컬렉션 클래스
    • 응용 프로그램에 특화된 커스텀 컬렉션을 작성하는데 사용하는 기반 클래스
  • 컬렉션 이름 공간들은 다음과 같다.
이름공간 내용
System.Collections 비제네릭 컬렉션 클래스들과 인터페이스들
System.Collections.Specialized 강한 형식의 비제네릭 컬렉션 클래스들
System.Collections.Generic 제네릭 컬렉션 클래스들과 인터페이스들
System.Collections.ObjectModel 커스텀 컬렉션을 위한 프록시들과 기반 클래스들
System.Collections.Concurrent 스레드에 안전한 컬렉션들

 

열거

  • 컴퓨팅에는 배열이나 연결 목록 같은 간단한 자료구조에서부터 적흑 트리(red/black tree)나 해시테이블 같은 복잡한 것에 이르기까지 다양한 종류의 컬렉션이 쓰인다.
    • 이런 자료구조들의 내부 구현과 외부 특징은 아주 다양하지만, 컬렉션의 내용을 운행하는(traverse) 능력, 다시 말해 컬렉션에 담긴 요소들에 차례로 접근할 수 있는 기능을 제공해야 한다는 점은 거의 보편적이다.
    • .NET Framework는 이를 위해 한 쌍의 인터페이스(IEnumerable과 IEnumerator, 그리고 해당 제네릭 인터페이스들)를 제공한다.
    • 이들을 구현함으로써 내부 구현과 외부 특징이 서로 다른 자료구조들이라도 공통의 운행 API를 소비자에게 노출할 수 있다.

Continue reading

C# 6.0 완벽 가이드/ .NET Framework의 기초

문자열과 텍스트 처리

Char

  • .NET Framework System.Char 구조체의 별칭인 C#의 char는 유니코드 문자 하나를 나타내는 형식이다.
    • (이래서 Char로 선언하나 char로 선언하나 완전히 동등하다. string도 마찬가지. char는 예약어이다.)
  • char의 ToUpper와 ToLower는 최종 사용자의 local 설정을 존중하는데, 이 때문에 미묘한 버그가 생길 수 있다.
    • 터키어 환경에서 char.ToUpper(‘i’) == ‘I’ 는 false가 된다.
    • 이런 문제를 해결하기 위해 System.Char, System.String은 ToUpper와 ToLower에 문화권 불변 버전들도 제공한다. 그 버전들은 항상 영어권 규칙을 적용한다.
    • char.ToUpperInvariant(‘i’) 또는 char.ToUpper(‘i’, CultureInfo.InvariantCulture))
  • char를 명시적으로 정수로 캐스팅함으로써, 유니코드 문자집합에 속하지 않는 문자 값을 char 변수에 배정하는 것도 가능하다. 주어진 문자가 유효한 유니코드 문자인지 알고 싶으면 char.GetUnicodeCategory 메서드를 사용하면 된다. 이 메서드를 호출한 결과가 UnicodeCategory.OtherNotAssigned면 유효한 문자가 아닌 것이다.
  • char의 너비는 16비트이다. 이는 기본 다국어 평면 (Basic Multiilngual Plane, BMP)에 있는 모든 유니코드 문자를 표현하기에 충분한 크기이다. 그 밖의 문자를 표현하려면 유니코드 대체 쌍(surrogate pair)을 사용해야 한다.

Continue reading

C# 6.0 완벽 가이드/ .NET Framework 개요

  • .NET Framework의 거의 모든 능력은 다종다양한 ‘관리되는 형식(managed type)’들을 통해 제공된다. 이 형식들은 계통구조(hierarchy) 형태의 이름공간들로 조직화되어 있으며, 일단의 어셈블리 파일들로 배포, 설치된다. 이들과 CLR(공용 언어 런타임)을 합친 것이 바로 .NET 플랫폼이다.
  • .NET Framework의 형식들 일부는 CLR이 직접 사용한다. 이들은 관리되는 호스팅 환경에 필수적인 형식들로, mscorlib.dll 이라는 어셈블리 안에 들어 있다.
    • C#의 내장 형식들과 기본 컬렉션 클래스들, 그리고 스트림 처리나 직렬화, 반영(reflection), 스레드 적용, 네이티브 상호운용성을 위한 형식들이 여기에 속한다.
  • 이보다 한 수준 위에는 CLR 수준의 기능성에 살을 붙이는 추가적인 형식들이 있다. 이들은 이를테면 XML 처리나 네트워킹, LINQ 같은 기능을 제공한다.
  • .NET Framework의 그 나머지 부분은 응용 API 들로 구성되어 있는데, 이들 대부분은 크게 다음과 같은 3가지 기능 영역으로 분류된다.
    • 사용자 인터페이스 기술
    • 뒷단(backend) 기술
    • 분산 시스템 기술
  • .NET Framework 4.6의 새로운 기능
    • 쓰레기 수거기가 수거를 실행하는 시점을 좀 더 세밀하게 제어할 수 있는 새 메서드들이 GC 클래스에 추가되었다.
    • 새롭고 더 빠른 64비트 JIT 컴파일러가 도입되었다.
    • System.Numerics 이름공간에 하드웨어 가속 행렬 및 벡터 형식들이 추가되었다.
    • 라이브러리 작성자를 위해 System.AppContext라는 새로운 클래스가 추가되었다. 이를 이용해 라이브러리를 작성하면 라이브러리 사용자가 새로운 API 기능들을 선택적으로 전환할 수 있다.
    • Task 인스턴스 생성시 현재 스레드의 문화 설정과 UI 문화 설정이 반영된다.
    • 더 많은 컬렉션 형식들이 IReadOnlyCollection<T>를 구현한다.
    • WPF가 개선되었다. (더 나은 터치 및 고 DPI 처리 등)
    • ASP.NET이 HTTP/2와 Window 10의 TBP(Token Binding Protocol)를 지원한다.
  • .NET Framework 4.5의 새로운 기능
    • Task를 돌려주는 메서드들을 통한 광범위한 비동기성 지원
    • ZIP 압축 프로토콜 지원
    • 새로운 HttpClient 클래스를 통한 HTTP 지원 개선
    • 쓰레기 수거기와 어셈블리 자원 조회 성능 향상
    • WinRT 상호운용성 및 Windows 스토어 모바일 앱 구축을 위한 API 지원
    • 새로운 TypeInfo 클래스 추가
    • 정규 표현식 부합시 만료 시간을 지정하는 능력 추가
    • 병렬 컴퓨팅 부분에서 생산자-소비자 스타일의 네트워크 구축을 위한 Dataflow라는 특화된 라이브러리가 추가

Continue reading

C# 6.0 완벽 가이드/ 고급 C#

대리자

  • 대리자(delegate)는 어떤 메서드를 호출하는 방법을 담은 객체
  • 대리자 형식은 그 형식의 인스턴스, 즉 대리자 인스턴스가 호출할 수 있는 종류의 메서드를 정의한다.
  • 메서드를 대리자 변수에 배정하면 대리자 인스턴스가 생성된다.
  • 대리자 인스턴스는 이름 그대로 호출자의 대리자 역할을 한다. 즉, 호출자가 대리자를 호출하면 대리자가 대상 메서드를 대신 호출해 준다. 이러한 간접 호출에 의해, 호출자와 대상 메서드 사이의 결합(coupling)이 끊어진다.
// 다음과 같은 문장은
Transformer t = Square;

// 다음 문장을 줄여 쓴 것이다.
Transformer t = new Transformer(Square);

// 한편 다음과 같은 표현식은
t(3);

// 다음을 줄여 쓴 것이다.
t.Invoke(3);

Continue reading

C# 6.0 완벽 가이드/ C#의 사용자 정의 형식

클래스

메서드

메서드에 적용할 수 있는 수정자들

정적 수정자 static
접근 수정자 public, internal, private, protected
상속 수정자 new, virtual, abstract, override, sealed
부분 메서드 수정자 partial
비관리 코드 수정자 unsafe, extern
비동기 코드 수정자 async

식 본문 메서드 (C# 6)

int Foo (int x) { return x * 2; }

int Foo (int x) => x * 2; // 위 코드와 동일

void Foo (int x) => Console.WriteLine(x); // 반환형이 void인 함수도 이런 식으로 사용할 수 있다.
  • 위의 코드와 같이 표현식이 본문인 메서드(expression-bodied method)를 줄여서 식본문 메서드라고 부른다. 중괄호와 return 키워드 대신 ‘이중 화살표’가 쓰였다.

Continue reading