반응형
Notice
Recent Posts
Recent Comments
Link
«   2025/05   »
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 29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

개발꿈나무

[C# 교과서] 7. C# 활용(1) - 닷넷 API(구조체, 열거형, 클래스) 본문

C# 기초

[C# 교과서] 7. C# 활용(1) - 닷넷 API(구조체, 열거형, 클래스)

HYOKYE0NG 2022. 1. 14. 14:54
반응형

닷넷 API 탐색기와 Docs

마이크로소프트는 닷넷 API 탐색기를 제공하여 웹에서 모든 API 검색을 할 수 있다.

 

.NET API browser

Learn more about: .NET API browser

docs.microsoft.com

 

클래스, 구조체, 열거형, 네임스페이스

  • 클래스(class): Console 클래스, String 클래스 등 거의 대부분이 클래스
  • 구조체(struct): DateTime 구조체, TimeSpan 구조체 형태로 표현하며, 클래스와 거의 동일하게 사용
  • 열거형(enumeration): Color 열거형 등이 있으며, 늑정 목록을 관리할 때 편리
  • 네임스페이스(namespace): System 네임스페이스처럼 많은 양의 클래스와 구초제, 열거형을 묶어서 관리

 

 

구조체

 

구조체란?

  • 구조체는 이름 하나로 데이터를 묶어 관리하는 역할
  • 변수와 배열을 확장하여 이름 하나로 데이터 형식을 1개 또는 여러 개 보관하는 그릇 역할
  • int, string 등 서로 다른 자료를 한 집단으로 정의하여 이름 하나로 지정 가능

 

구조체 만들기

struct 구조체이름
{
	데이터형식 변수1;
    데이터형식 변수2;
    데이터형식 변수3;
}

 

구조체를 사용하여 하나 이상의 변수 또는 배열을 묶어 관리하기

using System;

struct Point
{
    public int X; // public 키워드로 외부에서 int X 변수를 사용하도록 설정
    public int Y;
}

class StructDemo
{
    static void Main()
    {
        Point point; // Point 구조체 형식의 변수 선언
        point.X = 100; // 점을 구분해서 X 변수에 값을 할당
        point.Y = 200; // 점을 구분해서 Y 변수에 값을 할당
        Console.WriteLine($"X: {point.X}, Y: {point.Y}"); 
    }
}

//result: X: 100, Y: 200

 

구조체를 사용하여 변수 하나로 여러 개를 묶어 관리하기

using System;

class StructVariable
{
    static void Main()
    {
        // 구조체 형식 변수 선언
        Product product;
        // 구조체 변수의 각각의 멤버에 값을 할당 
        product.Id = 1;
        product.Title = "좋은 책";
        product.Price = 10000M;
        // 구조체 형식 변수 사용
        string message = 
            $"번호: {product.Id}\n상품명: {product.Title}\n가격: {product.Price}";
        Console.WriteLine(message);
    }
}

// 3개의 멤버(Member)를 가지는 Product 구조체 선언
struct Product
{
    // 구조체의 멤버가 되는 변수들은
    // public 액세스 한정자(Access Modifier)를 붙여서 외부에서 사용 가능하도록 설정
    public int Id; // 상품번호
    public string Title; // 상품명
    public decimal Price; // 가격
}

/*
<result>
번호: 1
상품명: 좋은 책
가격: 10000
*/

 

구조체 배열을 사용해서 데이터 대입 및 출력하기

using System;

namespace StructArray
{
    //[1] 구조체 선언
    struct BusinessCard
    {
        public string Name; // 이름
        public int Age; // 나이
    }

    class StructArray
    {
        // 출력 전담 함수
        static void Print(string name, int age) 
            => Console.WriteLine($"{name}은(는) {age}살입니다.");

        static void Main()
        {
            //[A] 구조체 변수: 하나의 이름으로 하나 이상의 데이터 형식을 하나 보관
            BusinessCard biz; // 구조체 형식 변수 선언
            biz.Name = "홍길동";
            biz.Age = 17;
            Print(biz.Name, biz.Age);

            //[B] 구조체 배열: 하나의 이름으로 하나 이상의 데이터 형식을 여러 개 보관
            BusinessCard[] names = new BusinessCard[2]; // 구조체 형식 배열 선언
            names[0].Name = "백두산"; names[0].Age = 102;
            names[1].Name = "임꺽정"; names[1].Age = 31;
            for (int i = 0; i < names.Length; i++)
            {
                Print(names[i].Name, names[i].Age);
            }
        }
    }
}

/*
<result>
홍길동은(는) 17살입니다.
백두산은(는) 102살입니다.
임꺽정은(는) 31살입니다.
*/

 

구조체 매개변수: 함수의 매개변수에 구조체 사용하기

using System;

namespace StructParameter
{
    // Member 구조체 선언
    struct Member
    {
        public string Name;
        public int Age;
    }

    class StructParameter
    {
        static void Main()
        {
            //[1] 변수 사용
            string name = "홍길동";
            int age = 21;
            Print(name, age); // 매개 변수를 따로 선언

            //[2] 구조체 사용 
            Member m;
            m.Name = "백두산";
            m.Age = 100;
            Print(m); // 구조체 매개 변수를 사용하여 전달
        }

        static void Print(string name, int age) =>
            Console.WriteLine($"이름: {name}, 나이: {age}");

        static void Print(Member member) =>
            Console.WriteLine($"이름: {member.Name}, 나이: {member.Age}");
    }
}

/*
<result>
이름: 홍길동, 나이: 21
이름: 백두산, 나이: 100
*/

 

내장형 구조체

  • DataTime 구조체: 시간/날짜 관련 모든 정보 제공
  • TimeSpan 구조체: 시간/날짜 간격에 대한 모든 정보 제공
  • Char 구조체: 문자 관련 모든 정보 제공
  • Guid 구조체: 절대로 중복되지 않는 유일한 문자열 생성

 

열거형 형식 사용하기

 

열거형 형식 사용하기

  • 열거형 형식은 기억하기 어려운 상수들을 기억하기 쉬운 이름 하나로 묶어 관리하는 표현 방식
  • 열거형을 사용하면 값 리스트 여러 개를 이름 하나로 관리 가능
  • 열거형은 enum 키워드를 사용하고 이늄 또는 이넘으로 읽음

 

ConsoleColor 열거형으로 콘솔의 전경색 및 배경색 바꾸기

using System;

class ConsoleColorDemo
{
    static void Main()
    {
        // 전경색
        Console.ForegroundColor = ConsoleColor.Blue;
        Console.WriteLine("Blue");
        Console.ResetColor();

        // 배경색
        Console.BackgroundColor = ConsoleColor.Yellow;
        Console.ForegroundColor = ConsoleColor.Red;
        Console.WriteLine("Red");
        Console.ResetColor();
    }
}

 

열거형 만들기

enum 열거형이름
{
	열거형변수1;
    열거형번수2;
    열서형변수3;
}

//열거형 선언할 때 기본값 설정
enum 열거형이름
{
	열거형변수1 = 기본값1;
    열거형변수2 = 기본값2;
    열거형변수3 = 기본값3;
}

 

열거형으로 관련 있는 항목을 묶어 관리하기

using System;

class EnumAnimal
{
    enum Animal { Mouse, Cow, Tiger }

    static void Main()
    {
        Animal animal = Animal.Tiger;
        Console.WriteLine(animal); // "Tiger"

        if (animal == Animal.Tiger)
        {
            Console.WriteLine("호랑이");
        }
    }
}

/*
<result>
Tiger
호랑이
*/

 

열거형 인덱스 순서 변경하기

열거형 인덱스의 기본값은 0, 1, 2이지만 새로운 값으로 설정 가능

using System;

enum Animal
{
    Horse,      // 0
    Sheep = 5,  // 1 => 5
    Monkey      // 2 => 6
}

class EnumIndexChange
{
    static void Main()
    {
        Console.WriteLine((int)Animal.Monkey); // 6
    }
}

// result: 6

 

열거형과 switch 문 함께 사용하기

열거형 값을 비교할 때는 switch문을 사용하면 편리한데, 열거형 값을 switch 문에 대입하면 자동으로 열거형 항목에 해당하는 case 문을 만드는 기능 제공

using System;

namespace EnumSwitch
{
    enum Animal { Chicken, Dog, Pig }

    class EnumSwitch
    {
        static void Main()
        {
            Animal animal = Animal.Dog;

            switch (animal)
            {
                case Animal.Chicken:
                    Console.WriteLine("닭");
                    break;
                case Animal.Dog:
                    Console.WriteLine("개");
                    break;
                case Animal.Pig:
                    Console.WriteLine("돼지");
                    break;
                default:
                    Console.WriteLine("기본값 설정 영역");
                    break;
            }
        }
    }
}

//result: 개

 

 

클래스 사용하기

 

클래스 소개하기

클래쓰는 C#의 핵심코드로 public class 클래스 이름{} 코드 블록을 사용하여 정의

 

클래스 정의

  • 클래스는 개체를 생성하는 틀(템플릿)
  • 클래스는 무엇인가를 만들어 내는 설계도

 

클래스의 구성요소

  • 속성: 데이터
  • 메서드: 로직

 

클래스 선언하기

public class 클래스이름
{
	//클래스 내용 구현
}

 

 

클래스 레벨의 메서드 호출하기

using System;

class ClassNote
{
    static void Run()
    {
        Console.WriteLine("ClassNote 클래스의 Run 메서드");
    }

    static void Main()
    {
        Run(); //[1] 메서드 레벨: 같은 클래스의 메서드 호출
        ClassNote.Run(); //[2] 클래스 레벨: 클래스.메서드() 형태로 호출
    }
}

/*
<result>
ClassNote 클래스의 Run 메서드
ClassNote 클래스의 Run 메서드
*/

 

static과 정적 메서드

static이 붙는 클래스의 모든 멤버는 해당 클래스 내에서 누구나 공유해서 접근 가능 -> 정적 메서드(공유 메서드)

 

정적메서드와 인스턴스 메서드

정적 메서드: static 키워드 존재, 클래스이름.멤버이름() 형태로 호출

인스턴스 메서드: static 키워도 존재하지 않음, new() 키워드 사용하여 개체 만든 후 사용 가능

using System;

class MyFirstClass
{
    static void StaticMethod() => Console.WriteLine("[1] 정적 메서드");

    void InstanceMethod() => Console.WriteLine("[2] 인스턴스 메서드");

    static void Main()
    {
        //[1] 정적 메서드 호출
        MyFirstClass.StaticMethod();
        //[2] 인스턴스 메서드 호출: new 키워드로 새로운 개체 생성하는 코드 모양
        MyFirstClass my = new MyFirstClass();
        my.InstanceMethod(); 
    }
}

/*
[1] 정적 메서드
[2] 인스턴스 메서드
*/

 

클래스 이름 짓기

  • 의미 있는 이름
  • 명사를 사용하며, 첫 글자는 대문자
  • 축약형이나 특정 접두사, 언더스코어(_) 같은 특수문자 쓰지 않음

 

클래스의 주요 구성 요소

  • 필드(field): 클래스(개체)의 부품 역할, 클래스 내에 선언된 변수나 데이터를 담는 그릇으로 개체 상태 저장
  • 메서드(method): 개체 동작이나 기능 정의
  • 생성자(construtor): 개체 필드 초기화, 개체를 생성할 때 미리 수행해야 할 기능 정의
  • 소멸자(destructor): 개체를 모두 사용한 후 메모리에서 소멸될 때 실행
  • 속성(property): 개체의 색상, 크기, 형태 등 정의

 

액세스 한정자

클래스를 생성할 때 public, private, internal, abstract, sealed 같은 키워드를 붙혀 클래스에 접근할 수 있는 범위 결정

 

클래스와 멤버

using System;

// [1][1] 클래스 생성
public class ClassName
{
    // [1][2] 멤버 생성: 메서드 멤버 생성
    public static void MemberName()
    {
        Console.WriteLine("클래스의 멤버가 호출되어 실행됩니다.");
    }
}

public class ClassAndMember
{
    public static void Main()
    {
        // [2][1] 클래스 사용
        ClassName.MemberName(); // 정적(Static) 멤버 접근
    }
}

클래스 멤버 중 static 키워드가 붙는 멤버들은 모두 정적인 멤버로 클래스이름.멤버이름(); 형태로 호출

 

환경 변수 사용하기

Environment클래스의 여러 가지 속성을 사용하여 컴퓨터의 환경 변수 값을 출력할 수 있음

using System;

class EnvironmentDemo
{
    static void Main()
    {
        // 시스템폴더: C:\Windows\system32
        Console.WriteLine(Environment.SystemDirectory);
        // 닷넷기준버전: 4.0.30319.42000
        Console.WriteLine(Environment.Version);
        // 운영체제 버전: Microsoft Windows NT 6.2.9200.0
        Console.WriteLine(Environment.OSVersion);
        // 컴퓨터명: VISUALACADEMY
        Console.WriteLine(Environment.MachineName);
        // 사용자명: RedPlus
        Console.WriteLine(Environment.UserName);
        // 현재 폴더: C:\C#\EnvironmentDemo\EnvironmentDemo\bin\Debug
        Console.WriteLine(Environment.CurrentDirectory);
        // 문서 폴더: C:\Users\RedPlus\Documents
        string docs = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
        Console.WriteLine(docs);
    }
}

 

EXE 파일 실행하기

Process 클래스의 Start() 메서드를 사용하여 프로그램 코드 내에서 exe 파일을 샐항할 수 있음

using System.Diagnostics;

namespace DotNet
{
    class ProcessStartDemo
    {
        static void Main()
        {
            //[1] 메모장을 실행합니다. 
            Process.Start("Notepad.exe"); 
            //[2] 웹 브라우저를 열고 매개 변수로 URL을 절달합니다.
            Process.Start("Explorer.exe", "https://dotnetkorea.com"); 
        }
    }
}

 

Random 클래스

  • Random 클래스를 사용하면 난수를 발생시킬 수 있음
  • Random 클래스는 인스턴스 클래스이기 때문에 new() 키워드로 인스턴스를 생성할 수 사용 가능
using System;

class RandomDemo
{
    static void Main()
    {
        // Random 클래스의 인스턴스 생성
        Random random = new Random();

        Console.WriteLine(random.Next());       // 임의의 정수
        Console.WriteLine(random.Next(5));      // 0 ~ 4
        Console.WriteLine(random.Next(1, 10));  // 1 ~ 9
    }
}

 

Random 클래스 사용하여 가위바위보 게임 만들기

using System;

class RockPaperScissors
{
    static void Main()
    {
        int iRandom = 0; // 1(가위), 2(바위), 3(보)
        int iSelection = 0; // 사용자 입력(1~3)

        //[!] 0번째 인덱스 "가위", 1번째 인덱스 "바위", 2번째 인덱스 "보"
        string[] choice = { "가위", "바위", "보" }; 

        // 컴퓨터의 랜덤값 지정 (1, 2, 3 중 하나)
        iRandom = (new Random()).Next(1, 4);

        Console.Write("1(가위), 2(바위), 3(보) 입력: _\b");
        iSelection = Convert.ToInt32(Console.ReadLine());

        //[!] 사용자로부터 입력받은 값에서 1을 빼야 배열의 인덱스에 위치하는 문자열과 일치 
        Console.WriteLine("\n 사용자: {0}", choice[iSelection - 1]);
        Console.WriteLine(" 컴퓨터: {0}\n", choice[iRandom - 1]);

        // 결과 출력
        if (iSelection == iRandom)
        {
            Console.WriteLine("비김");
        }
        else
        {
            switch (iSelection)
            {
                case 1: Console.WriteLine((iRandom == 3) ? "승" : "패"); break;
                case 2: Console.WriteLine((iRandom == 1) ? "승" : "패"); break;
                case 3: Console.WriteLine((iRandom == 2) ? "승" : "패"); break;
            }
        }
    }
}

 

정규식

정규식은 문자열에서 특정 패턴을 찾아주는 기능 수행

 

정규식으로 공백 여러 개를 하나로 변경하기

using System;
using System.Text.RegularExpressions;

class RegexReplace
{
    static void Main()
    {
        string s = "안녕하세요.    반갑습니다.    또 만나요.";
        var regex = new Regex("\\s+"); // 하나 이상의 공백 패턴 검사
        string r = regex.Replace(s, " "); // 하나 이상의 공백을 공백 하나로 변환
        Console.WriteLine(s);
        Console.WriteLine(r);
    }
}

 

정규식을 사용하여 이메일 형태인지 검증하기

using System;
using System.Text.RegularExpressions;

class RegexDemo
{
    static void Main()
    {
        // 정규 표현식 관련 클래스: Regex
        string email = "abcd@aaa.com";
        Console.WriteLine(IsEmail(email));
    }

    static bool IsEmail(string email)
    {
        bool result = false;

        //[!] 이메일을 검사하는 정규식은 인터넷에서 검색하여 사용 가능
        Regex regex = new Regex(
            @"^[A-Za-z0-9](([_\.\-]?[a-zA-Z0-9]+)*)@([A-Za-z0-9]+)" +
            @"(([\.\-]?[a-zA-Z0-9]+)*)\.([A-Za-z]{2,})$");

        result = regex.IsMatch(email); // 패턴이 맞으면 True

        return result;
    }
}

 

값 형식과 참조 형식

  • 값 형식: 개체에 값 자체를 담고 있는 구조 (ex) int, double
  • 참조 형식: 개체가 값을 담고 있는 또 다른 개체를 포인터로 바라보는 구조, 여러 값이 동일한 개체 가리킬 수 있음

 

박싱과 언박싱

  • 박싱: 값 형식의 데이터를 참조 형식의 데이터로 변환하는 작업, 스택 메로리 영역에 저장된 값 형식의 데이터를 힙 메모리 영역에 저장하는 단계를 거치기 때문에 시간과 공간 소비비용 발생
  • 언박싱(캐스팅): 참조 형식의 데이터를 값 형식의 데이터로 변환하는 과정

 

is 연산자와 as 연산자

  • is 연산자: 특정 개체가 특정 형식인지 검사
  • as 연산자: 특정 데이터를 특정 데이터 형식으로 변환, 해당 데이터 형식이면 변환하고 그렇지 않으면 null 반환
//is 연산자로 형식 확인하기
object x = 1234;
if(x is int)
{
	Console.WriteLine($"{x}는 정수형으로 변환 가능");
}
// -> 1234는 정수형으로 변환 가능


//as 연산자로 형식 변환하기
object x = 1234;
string s = x as String;
Console.WriteLine(s == null ? "null" : s);
// -> null
// 정수 형식의 데이터는 as 연산자로 string 형식으로 변환 불가능

 

반응형
Comments