본문 바로가기

C# 공부/C# 기본 문법

클래스 - 4 (중첩클래스, 분할클래스, 확장메소드, 구조체, 튜플)

A. 중첩클래스 (Nested Class)

중첩 클래스는 클래스내에 선언된 클래스이다.

Class OuterClass
{
	Class NestedClass
    {
    }
}

- 특징 : 자신이 소속된 클래스의 private멤버에도 자유롭게 접근할수있다.

- 장점, 사용하는 상황?

1. 클래스 외부에 공개하고 싶지 않은 형식을 만들고자 할 때

2. 현재 클래스의 일부분처럼 표현할 수 있는 클래스를 만들고자 할때

class Configuration
    {
        List<ItemValue> listConfig = new List<ItemValue>();

        public void SetConfig(string item,string value)
        {
            ItemValue iv = new ItemValue();
            iv.SetValue(this, item, value);
        }
        public string GetConfig(string item)
        {
            foreach(ItemValue iv in listConfig)
            {
                if (iv.GetItem() == item)
                    return iv.GetValue();
            }
            return "";
        }
        private class ItemValue
        {
            private string item;
            private string value;

            public void SetValue(Configuration config, string item, string value)
            {
                this.item = item;
                this.value = value;

                bool found = false;
                for(int i = 0; i < config.listConfig.Count; i++)
                {
                    if (config.listConfig[i].item == item)
                    {
                        config.listConfig[i] = this;
                        found = true;
                        break;
                    }
                }
                if (found == false)
                    config.listConfig.Add(this);
            }
            public string GetItem() { return item; }
            public string GetValue() { return value; }
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            Configuration config = new Configuration();
            config.SetConfig("Version", "V 5.0");
            config.SetConfig("Size", "655,324KB");

            Console.WriteLine(config.GetConfig("Version"));
            Console.WriteLine(config.GetConfig("Size"));

            config.SetConfig("Version", "V 5.0.1");
            Console.WriteLine(config.GetConfig("Version"));
        }
    }

 

B. 분할 클래스(Partial Class)

partial 키워드를 통해 나눠서 구현하는 클래스이며, 클래스의 구현이 길어질 경우 여러파일에 나눠서 구현할수있게 함으로써 소스코드 관리의 편의를 제공한다.

partial class MyClass
{
	public void Method(){}
    public void Method2(){}
}

partial class MyClass
{
	public void Method3(){}
    public void Method4(){}
}

 

C. 확장 메소드(Extension Method)

기존 클래스의 기능을 확장하는 기법이다. 이 기법으로 string 클래스 또는 int 형식에 기능추가 가능.

선언방법은 static한정자로 수식해야하며, 이 메소드의 첫번째 매개 변수는 반드시 this키워드와 함께 확장하고자 하는 클래스(형식)의 인스턴스여야 한다. 

public static class IntegerExtension
{
	public static int Power(this int myInt, int exponent)
    {
    	int result=myInt;
        for(int i=1;i<exponent;i++)
        	result=result*myInt;
            
        return result;    
    }
}

<사용시>

using MyExtension;//확장 메소드를 담는 클래스의 네임스페이스를 사용
//---
int a=2;
Console.WriteLine(a.Power(3)); //마치 Power() 메소드가 int 형식의 메소드였떤것처럼 사용가능, 8출력
Console.WriteLine(10.Power(4)); //10*10*10*10
public static class StringExtension
    {
        public static string Append(this string myStr,string appendedStr)
        {
            string x = myStr;
            x = x + appendedStr;
            return x;
        }

    }
    class Program
    {
        static void Main(string[] args)
        {
            //string a = "Hello";
            Console.WriteLine("Hello".Append(", World"));
        }
    }

 

D. 구조체

1. 구조체의 장점 : 구조체는 값형식이므로, 구조체의 인스턴스는 스택에 할당되고 선언된 블록이 끝나는 지점에 메모리에서 사라진다. 

2. 클래스와 구조체의 차이

특징 클래스 구조체
키워드 class struct
형식 참조 형식 값 형식
복사 얕은 복사(Swallow Copy) 깊은 복사(Deep Copy)
인스턴스 생성 new 연산자와 생성자 필요 선언만으로도 생성
생성자 매개 변수 없는 생성자 선언 가능 매개 변수 없는 생성자 선언 불가능
상속 가능 모든 구조체는 System.Object형식을 상속하는 System.ValueType으로부터 직접상속받음

 

E. 튜플 (Tuple)

튜플은 여러필드를 담을 수 있는 구조체이지만, 구조체와는 달리 형식의 이름을 갖지않는다. (구조체와 똑같이 스택에 할당되므로 프로그램에 부담을 주지 않음)

응용 프로그램 전체에서 사용할 양식을 선언할 때가 아닌, 임시적으로 사용할 복합데이터 형식을 선언할 때 적합하다.

var tuple = (123,789); // Item1, Item2라는 필드명으로 자동저장됨
Console.WriteLine($"{tuple.Item1},{tuple.Item2)");

- 명명된 튜플(Named Tuple) : ' 필드명 : '의 꼴로 필드 이름을 지정하여 선언 및 사용.

var tuple = (Name : "박규태". Age : 27);
Console.WriteLine($"{tuple.Name}, {tuple.Age}");

- 튜플의 분해는 튜플을 정의할때와는 반대로 사용한다. 이때 특정필드를 무시하고싶다면 _를 사용.

var tuple = (Name : "박규태". Age : 27);
var(Name,Age) = tuple //분해
Console.WriteLine($"{Name}, {Age}");

//또는

var tuple = (Name : "박규태". Age : 27);
var(Name,_) = tuple //분해+Age 무시
Console.WriteLine($"{Name}");

* 튜플사용시에는 System.Value Type이라는 추가패키지가 필요하며 , [도구] -> [Nuget 패키지관리자] -> [패키지 관리자 콘솔] -> Install-Package "System.ValueTuple" 명령어 입력으로 설치 후 사용한다.