본문 바로가기

전체 글

(59)
20. 람다식(Lambda Expression) 프로그램을 설계하면서, 간혹 한번만 사용하고싶은 함수가 있을 때가 있다. 이번 한번만 사용하고, 이후에 다시 재사용할 일이 없을 것 같아서 따로 함수를 선언하기 애매한 일회용 함수들. 혹은, 매개변수를 넘길 때, 기존의 값을 연산한 값으로 넘기고 싶을 때가 있다. 예를 들면 이런 식으로 말이다. public delegate int Calculate(int a, int b); static void Main(string[] args) { Calculate cal; cal = delegate(int a, int b) { return a + b; }; } 이렇게 함은, 대리자에 메서드를 전달하고 싶을 때, 기존의 메서드를 이용할 수는 없고, 그렇다고 새로 만들자니 다시 사용할 일 없는 함수를 전달하고자 할 때,..
19 - 1. 이벤트 VS 대리자 앞선 19장에서 다루었던 이벤트와 대리자의 형식이 굉장히 유사하였고, 특징들도 굉장히 유사했는데, 그렇다면 이 둘을 구분지은 이유는 무엇일까? 사용함에 있어서 어떻게 다르고, 무엇이 가능한지, 무엇이 불가능한지에 대한 차이를 알아보도록 하자. 우선 메서드 등록시에 유의점이다. 대리자와 이벤트 둘 모두 +=을 통해 메서드들을 저장할 수 있다는 공통점이 존재한다. 다만, = 대입연산자를 통해 메서드를 하나로 지정하는 것은 대리자에게만 허용되고, 이벤트는 대입연산자의 사용이 허용되지 않는다. 이에 대한 예시를 들어보자. sender는 이벤트와 대리자를 내부에 갖고있는 클래스의 객체이고, reciever들은 대리자 혹은 이벤트에 저장할 메서드, func이 담겨있는 객체라고 가정해보자. //... sender.D..
19. 이벤트(Event) 이벤트는 어떠한 사건이 발생함, 혹은 사건 자체를 일컫는 말이다. 프로그래밍에서 어떠한 사건이 발생하거나, 사건 자체에 해당하는 것은 무엇이 있을까? 우리가 객체지향을 하면서, 객체들이 여러가지 상호작용을 통해서 상태가 변화하는 등의 변화가 있을 것이다. 우리는 변화가 바뀌는 것 혹은 변화 그 자체를 이벤트라고 생각할 수 있겠다. 슈퍼마리오 게임을 예로 들자면, 마리오가 길을 가다가 코인을 획득했다고 가정해보자. 이 때, 코인을 획득했을 때 여러 객체들 사이에서 상호작용이 일어난다. 예를 들면, 코인의 갯수를 알려주는 UI는 보유 코인 갯수를 갱신할 것이고, 음향효과를 담당하는 객체에서는 코인 획득 시, 짤랑 하고 코인을 획득하는 효과를 출력할 것이며, 코인의 이펙트를 담당하는 객체에서는 코인이 빙글빙글..
18. 대리자 (Delegate) 대리자(Delegate)란, 정해진 매개변수와 반환타입이 일치하는 메서드에 대한 참조를 저장하여, 해당 메서드를 호출하는 기능을 한다. 예를들어, 정수 두개를 매개로 받아 서로 더한 정수값을 반환하는 int Sum(int a, int b) 와, 정수 두개를 매개로 받아 서로 곱한 정수값을 반환하는 int Mul(int a, int b)가 있다고 가정해보자면, 두 메서드 모두 반환값이 int로 동일하고, 매개변수로 두개의 정수를 입력받기 때문에, 해당 메서드를 하나의 대리자로 호출할 수 있다. 대리자의 선언 및 참조저장방식은 다음과 같다. public int Sum(int a, int b) { return a + b; } public int Mul(int a, int b) { return a * b; } ..
17. 예외처리(Exception Handling) 코딩하면서, 런타임에러가 발생하지 않았는데도 컴파일중에 에러가 생기는 경우가 있다. IndexOurofRange, FormatException등 신기한 언어들이 코딩중인 나를 괴롭히는 경우가 허다하다. 이러한 경우는 처리되지 않은예외를 컴파일러에서 스스로 감지하여 이용자에게 알려주는 것이다. 이렇게 예외를 처리하지 않은 채 프로그램을 실행하면, 처리되지 않은 예외를 만나는 순간 프로그램이 다운되기 때문에, 미리 예외를 처리하는 것이 좋다. 예외처리를 함으로써, 이용자가 인지하지 못하는 예외가 발생해 프로그램이 다운되는 것을 막을 수 있으며, 어느부분에서 예외가 발생했는지를 인지하고, 유동적으로 디버깅을 할 수 있기 때문이다. 예외처리를 하는 방법 역시 다양한데, 먼저는 if 분기문으로 발생가능한 예외를 ..
16. 일반화 (Generic <T>) 어떠한 기능이 필요해서 함수를 선언하고 정의하다보면, 같은 기능인데 여러 자료형들도 사용할 수 있도록 만들고싶어질 때가 있다. 자료형을 가리지 않고 사용할 수 있는 함수를 구현하기 위해서, C++에서는 template을 사용했었다. 그러나 c#에서는 템플릿 대신 다른 개념이 등장하게 되었는데, 이번엔 그 개념에 대해서 알아보겠다. 특정 함수의 기능에 대해, 자료형을 특정하지 않고 여러 자료형들도 해당 기능을 사용하기 위해, c#에서는 함수를 일반화 한다. 함수의 일반화란, 함수의 매개변수의 자료형을 특정하지 않고 일반화 하여, 어떤 자료형이든 매개변수로 넘길 수 있도록 하는 것이다. 함수의 일반화 방법은 다음과 같다. using System; namespace Favor { internal class P..
15. 연산자 오버로딩 객체지향 프로그래밍을 하면서, 객체들의 요소를 서로 비교하거나, 더할 때가 생긴다. 예를들면, A라는 사람과 B라는 사람을 객체로 두고, 이 사람들의 소지금을 요소라고 가정했을 때, 우리가 A의 소지금에서 B의 소지금을 빼려고 하면 A.money - B.money 와 같은 연산이 필요했다. 이런 경우에서 더 나아가, 소지금 뿐 아니라 나이, 키, 몸무게 등 여러가지 요소를 비교하거나, 더하고 빼는 등, 각 객체들의 요소를 연산하고 싶어질 때가 많으면 많을수록, 많은 연산을 반복해야한다는 번거로움이 생긴다. 또한, 이렇게 연산한 값을 가진 새로운 객체를 만들고자 한다면, 구조가 많이 복잡해질 수 있다. 이럴때, 객체들끼리 + 연산자를 통해서 서로가 가진 요소들을 더할수는 없을까? 이러한 기능을 연산자 오버..
14. Array 클래스 여러 자료형들을 관리함에 있어, 우리는 다양한 자료형으로 배열을 선언하고 관리하였다. using System; namespace Favor { internal class Program { static void Main(string[] args) { int[] iArr = new int[4]; } } } 그런데 무언가 낯익은 형태가 보인다. new로 인스턴스 하는 모습이 꼭 클래스를 선언할 때와 닮아있지 않은가? 물론 new 키워드를 통한 선언이 모두 클래스이진 않지만, 그것을 얘기하려는 것은 아니다. 바로 우리가 사용하던 이 배열조차도, 기본 자료형이 아니라 클래스로 구현되어있다는 것이다. string만 그런 것이 아니라 배열 역시 클래스였던 것이다. 이쯤 되면 다른 기본 자료형도 혹시...? 싶은 생각..