64. 부록 B. 팁과 트릭

  • 14 minutes to read

이번 부록에서는 본문에서 다루지 않은 몇가지 팁을 정리하였습니다. 가볍게 읽어보면 됩니다.

64.1. 인텔리센스(IntelliSense)와 코드 조각(Code Snippet)

코드 편집기에서 제공하는 기능 중에서 인텔리센스는 자동으로 코드 입력을 도와주고 가이드해주는 기능을 말합니다. 메모장과 같은 에디터는 모든 내용을 직접 입력해야하지만 Visual Studio와 Visual Studio Code와 같은 전문 도구는 인텔리센스의 도움을 받아서 좀 더 빠르고 정확하게 소스 코드를 작성할 수 있습니다.

64.1.1. Visual Studio의 인텔리센스

Visual Studio에서는 타이핑에서의 실수를 방지할 수 있는 인텔리센스 기능을 제공합니다. 만약 현재 작성중인 코드 위치에서 필요한 특정한 명령어가 생각나지 않을 때에는 코드 입력 창에서 Ctrl+SpaceBar를 누르면 관련 가이드를 받아 볼 수 있습니다.

코드 작성 영역에서 cla 정도만 입력하면 다음과 같이 클래스용 코드 조각을 볼 수 있습니다.

그림: 인텔리센스

IntelliSense

cla 입력 후 탭을 두 번 입력하거나, class 입력 후 탭을 두번 입력하면 다음과 같이 자동으로 클래스 코드가 생성됩니다. 생성된 코드에서 클래스 이름을 변경 후 엔터를 누르면 해당 이름으로 클래스가 생성됩니다.

cla class

기타 Visual Studio에서는 인텔리센스 기능 외에 코드 조각, 코드 감싸기, 리팩터링 기능들을 제공합니다.

64.1.2. 인텔리코드(IntelliCode)

인텔리센스의 기능 실행 중에 해당 시점에서 가장 많이 사용되는 API가 다음 그림과 같이 별표로 제공되는 기능을 제공하는데 이를 인텔리코드라고 합니다.

그림: 인텔리코드

Intellicode

64.1.3. 인텔리센스와 인텔리코드의 도움을 받으며 코드 작성하기

이제 인텔리센스 기능을 사용해보겠습니다. 주석의 내용을 실제 코드에 적용해서 네임스페이스, 클래스, Main() 메서드 그리고 Console.WriteLine() 메서드까지의 코드를 빠르게 작성해 보세요.

코드: IntelliSenseDemo.cs

//[!] 인텔리센스(IntelliSense): 코드 조각(Code Snippet)에 의한 자동 완성 기능
using System;

// namespace 탭탭
namespace IntelliSenseDemo
{
    // class 탭탭
    class IntelliSenseDemo
    {
        // svm 탭탭
        static void Main(string[] args)
        {
            // cw 탭탭
            Console.WriteLine("Visual Studio의 인텔리센스(IntelliSense)");

            // [Ctrl+Space]와 IntelliCode 제안
            Console.WriteLine("Visual Studio의 인텔리코드(IntelliCode)");
        }
    }
}
Visual Studio의 인텔리센스(IntelliSense)
Visual Studio의 인텔리코드(IntelliCode)

64.2. 자리 표시자 주요 서식

이번에는 서식 지정자(자리 표시자(Place Holder))의 주요 서식을 정리하였습니다.

64.2.1. 자리표시자 주요 서식

자리 표시자는 간단히는 인덱스만을 표현하지만, {인덱스,길이:서식}과 같은 형태로 추가적인 서식을 지정할 수 있습니다. {n} 형태에 추가적으로 옵션을 줄 수 있는데, {0, 10} 식으로 10칸을 잡아놓고 데이터를 출력하거나, {0:C} 형태로 C는 통화량을 의미하는 키워드로 원 단위로 표시가 됩니다.

표: 자리표시자 서식

자리표시자 서식 설명
{0,5} 5칸 잡고, 0번째 인덱스의 값을 표현
{0,5:F3} 5칸 잡고, 부동소수점 실수를 소수점 3자리까지 표현
{0:N} 3자리마다 콤마로 구분해서 출력
- D 10진수 표시
- X 16진수 표시
- C 통화량 표시
- E 부동 소수점(지수) 표시
- F 부동 소수점(기본) 표시
- G 부동 소수점(E, F와 비슷) 표시
- N 콤마 구분 표시

예를 들어 {0, -10:C} 형태의 서식을 사용하면 10칸 자리를 잡고 데이터를 통화량으로 마이너스 기호에 의해서 왼쪽 정렬로 출력되는 형태입니다.

C# Interactive에서 다음 내용을 순서대로 실행해 보세요.

> Console.WriteLine("자리" + "표시자");
자리표시자
> Console.WriteLine("{0} {1} {2}", "안녕", "방가", "또봐");
안녕 방가 또봐
> Console.WriteLine("{0} {1} {0}", "안녕", "또봐");
안녕 또봐 안녕
> Console.WriteLine("[{0,-10:C}]", 1234);// 왼쪽 원 표시
[₩1,234    ]
> Console.WriteLine("{0,10}", 1234); // 10칸 잡고 오른쪽 정렬
      1234
> Console.WriteLine("{0,-10}", 1234); // 10칸 잡고 왼쪽 정렬
1234      
> Console.WriteLine("{0,10:D}", 16); // 10진수: 16
        16
> Console.WriteLine("{0,10:X}", 16); // 16진수: 10
        10
> Console.WriteLine("{0,10:N}", 1234); // 콤마구분: 1,234.00
  1,234.00
> Console.WriteLine("{0,10:C}", 1234); // 통화량: \1,234
    ₩1,234
> Console.WriteLine("{0,10:E}", 1234.5678); // 1.234568E+003
1.234568E+003
> Console.WriteLine("{0,10:F}", 1234.5678); // 1234.57
   1234.57
> Console.WriteLine("{0,10:G}", 1234.5678); // 1234.5678
 1234.5678

참고로, 자리 표시자의 여러 서식은 외울 필요없이 그때 그때 서식을 찾아서 사용하면 됩니다.

64.3. checkedunchecked

프로그램을 작성하다보면 원하는대로 결괏값이 나타나지 않은 경우가 많이 발생합니다.예를 들어, 다음 코드를 작성하면 256이 아닌 0이 나타납니다.

> byte b = 255;
> b++;
> b
0

byte 형식은 0부터 255까지의 작은 정수를 담을 수 있는 그릇인데 255인 상태에서 1을 증가시키게 되면 256이 되는게 아니라 오버플로우가 발생하여 다시 0이 됩니다.

C# 컴파일러는 위 오버플로 에러는 기본값으로 발생시키지 않습니다.

오버플로 오류를 방지하려면 산술 연산 구문을 checked {} 구문으로 묶어주면 다음과 같이 오류를 발생시킵니다.

> byte b = 255;
> checked
. {
.    b++;
. }
산술 연산으로 인해 오버플로가 발생했습니다.

작은 값을 감소시킬때에도 동일한 예외가 발생합니다.

> byte b = 0;
> checked
. {
.    b--;
. }
산술 연산으로 인해 오버플로가 발생했습니다.

checked와 달리 unchecked는 오버플로 예외를 발생시키지 않습니다.

> byte b = 255;
> unchecked { b++; }
> b
0

64.4. 전처리기 지시문(Preprocessor Directive)과 조건부 컴파일

C#에서는 #define, #if, #esle, #endif 등을 사용하여 조건부 컴파일을 할 수 있습니다.

참고로, 이러한 구문은 C/C++의 전처리기 지시문(Preprocessor)과 비슷한 의미를 가집니다.

코드: DefineDemo.cs

#define YES

using System;

class DefineDemo
{
    static void Main()
    {
#if YES
        Console.WriteLine("YES");
#else
        Console.WriteLine("NO");
#endif
    }
}
YES

#define 기호를 사용하여 YES를 정의해 놓으면 #if YES 코드 영역이 실행됩니다. 이러한 기능은 C# 코드 외부에서 컴파일러 설정 값으로 들어오는 조건에 따라서 다르게 컴파일할 때 사용될 수 있습니다.

64.5. 암호화 연습: 초간단 문자열 인코딩 및 디코딩

프로그래밍 영역에서 읽기 쉬운 문자열을 읽기 어려운 암호화된 문자열로 변경하는 것은 자주 사용되고 많은 API와 알고리즘이 있습니다. StringByte로 변경하는 것을 인코드(Encode)라 하며 반대로 ByteString으로 변경하는 것을 디코드(Decode)라고 합니다. 간단하게 문자열을 암호화하는 방식으로는 Base64를 사용하여 문자열을 암호화할 수 있습니다.

이번에는 문자열을 인코딩하고 디코딩하는 방법을 데모 소스로 살펴보겠습니다.

코드: StringConverterDemo.cs

//[!] 초간단 문자열 인코딩 및 디코딩
using System;

namespace StringConverterDemo
{
    /// <summary>
    /// 문자열 변환기
    /// </summary>
    public class StringConverter
    {
        /// <summary>
        /// 초간단 문자열 인코딩
        /// </summary>
        public static string ConvertToSimpleEncoding(string original)
        {
            byte[] byt = System.Text.Encoding.UTF8.GetBytes(original);
            return System.Convert.ToBase64String(byt); // 암호화
        }
        /// <summary>
        /// 초간단 문자열 디코딩
        /// </summary>
        public static string ConvertToSimpleDecoding(string modified)
        {
            byte[] byt = System.Convert.FromBase64String(modified);
            return System.Text.Encoding.UTF8.GetString(byt); // 복호화
        }
    }
    class StringConverterDemo
    {
        static void Main()
        {
            string s = "안녕하세요.";
            Console.WriteLine("[1] 원본: {0}", s);

            s = StringConverter.ConvertToSimpleEncoding(s); // 인코딩
            Console.WriteLine("[2] 인코딩: {0}", s);

            s = StringConverter.ConvertToSimpleDecoding(s); // 디코딩
            Console.WriteLine("[3] 디코딩: {0}", s); 
        }
    }
}
[1] 원본: 안녕하세요.
[2] 인코딩: 7JWI64WV7ZWY7IS47JqULg==
[3] 디코딩: 안녕하세요.

사실, 암호화 기술은 굉장히 복잡한 기술이지만 그 기본은 이번 예제에서 살펴본 것처럼 "안녕하세요." 문자열을 "7JWI64WV7ZWY7IS47JqULg=="와 같이 사람이 읽기 어렵게 만드는 것입니다. 닷넷에서 사용할 수 있는 암호화 API는 "C# 암호화", ".NET 암호화" 등을 검색해 보기 바랍니다.

64.6. C#에서 이메일 전송하기

이번에는 C#에서 외부 서비스를 통해서 이메일을 전송하는 방법에 대해 알아봅니다.

64.6.1. 이메일 보내기

C#에서 Email을 전송하는 기능은 C# 고유 기능이라기 보다는 메일 서버의 SMTP 서비스를 .NET에서 사용하는 외부 서비스 개념입니다. 그러기에 메일 전송에 대한 방법은 정형화되지 못하고 많은 방법과 많은 수의 외부 패키지를 사용할 수 있으므로 이번 부록에서는 닷넷프레임워크 기반의 C#에서 외부 SMTP 서비스를 사용하여 메일을 보내는 내용을 다뤄보고자 합니다.

64.6.2. System.Net.Mail 네임스페이스

C#에서 Email(이메일)을 전송하려면 System.Net.Mail 네임스페이스에 있는 여러 가지 클래스들을 사용하여야 합니다. 메일 전송 관련 주요 클래스는 아래 표와 같습니다.

표: 이메일 보내기 관련 주요 클래스

클래스명 설 명
SmtpClient SMTP 메일 서비스를 사용하여 메일을 전송하는 부분을 담당한다
MailMessage 메일의 주요 항목(받는 이, 보내는 이, 내용 등)을 구성하는 개체를 생성한 후 SmtpClient 클래스에게 전달한다.
Attachment 메일 전송시 파일 첨부와 관련된 부분을 담당한다.
MailAddress 전송할 메일의 주소를 저장할 개체를 생성한다.

64.6.3. C#에서 MS 계정을 사용하여 전자 메일 전송하기

C#에서 Microsoft 계정의 정보를 사용하여 메일을 보낼 수 있습니다. 다음 샘플 코드를 작성 후 실행해보세요. 참고로, 이번 코드는 실행을 해도 메일이 정상적으로 전송되지 않을 수 있습니다. 대부분의 메일 서비스 업체는 이미 잘 알려진 메일로부터 오는 것 이외의 메일은 받지 않을 수 있기 때문입니다.

코드: SendMailTest.cs

using System.Net;
using System.Net.Mail;

class SendMailTest
{
    static void Main()
    {
        SmtpClient SmtpServer = new SmtpClient("smtp.live.com");
        var mail = new MailMessage();
        // [1] 보내는 이메일 넣는 곳
        mail.From = new MailAddress("youremail@yourdomain");
        // [2] 받는 이메일 넣는 곳
        mail.To.Add("youremail@yourdomain"); 
        mail.Subject = "메일 보내기 테스트";
        mail.IsBodyHtml = true;
        string htmlBody;
        htmlBody = "안녕하세요. <em>아웃룩</em> 메일 보내기 테스트입니다.";
        mail.Body = htmlBody;
        SmtpServer.Port = 587;
        SmtpServer.UseDefaultCredentials = false;
        // [3] outlook.com 이메일 계정 정보
        SmtpServer.Credentials = 
            new NetworkCredential("youremail@yourdomain", "password"); 
        SmtpServer.EnableSsl = true;
        SmtpServer.Send(mail);
    }
}

이메일 전송 결과

위 코드의 [1], [2], [3]번 코드에 Microsoft 계정의 정보를 정확히 입력하면, 닷넷프레임워크 기반의 C# 콘솔 응용 프로그램에서 메일을 전송할 수 있습니다. 이러한 방식으로 C#에서는 굉장히 많은 방식으로 메일을 보내주는 기능을 제공하는데요. 이번 예제는 그러한 여러 방식 중 하나로 참고로 실행해 보면 됩니다.

VisualAcademy Docs의 모든 콘텐츠, 이미지, 동영상의 저작권은 박용준에게 있습니다. 저작권법에 의해 보호를 받는 저작물이므로 무단 전재와 복제를 금합니다. 사이트의 콘텐츠를 복제하여 블로그, 웹사이트 등에 게시할 수 없습니다. 단, 링크와 SNS 공유, Youtube 동영상 공유는 허용합니다. www.VisualAcademy.com
박용준 강사의 모든 동영상 강의는 데브렉에서 독점으로 제공됩니다. www.devlec.com