Wanna be Brilliant Full-Stack Developer

C# WINFORMS 캡슐화, Partial Class 본문

Some Memos/C#

C# WINFORMS 캡슐화, Partial Class

Flashpacker 2023. 4. 14. 14:00

Partial Class 는 분리클래스라고 불리는데 클래스를 쪼개는것이다.

하나는 변수만 모아놓는 클래스, 계산함수만 모아놓는 클래스, 메시지 출력만 해놓은 클래스를 CData라는 클래스가

실제로는 하나지만 가상으로 분리해놨다고 말할 수 있다.

 

클래스를 기능별로 구분할때 나중에 찾을때 편하니까 이렇게 해놓는것이다. 

 

실제로 우리가 만들 프로그램은 마트 계산대와 같은것을 구현할것이다!

Enum에 보면 클래스 내부에 보통 지정을 하는데 다른 클래스들에서 다 접근을 하려면 안될 수가 있기 때문에

그래서 외부에 설정할 수 있다.

그래서 Form1에서도 불러다 쓰고 다른 클래스에서도 불러다 쓸수 있도록 할것이다.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Partial
{

     /// <summary>
     /// 변수
     /// </summary>
    partial class Cdata
    {

    }

    partial class Cdata
    {

    }


    partial class Cdata
    {

    }


    partial class Cdata
    {

    }
}

이렇게 partial만 붙이면 똑같은 클래스를 여러개 만들 수 있다.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Partial
{

     /// <summary>
     /// 변수
     /// </summary>
    partial class Cdata
    {
        private string strItem = string.Empty;
        private int iRate = 0;
        public int iCount = 0;

        public int IRate { get => iRate; set => iRate = value; }

        public string GetStrItem()
        {
            return strItem;
        }

        public void SetStrItem(string value)
        {
            strItem = value;
        }
    }

    partial class Cdata
    {

    }

    partial class Cdata
    {

    }


}

또한 이렇게 외부에서 접근을 제한할 수도 있고, 저런식으로해서 접근을 제어할 수도 있다.

자주쓰이는거는 

이 방법이다. 람다식이 보이는데?

이것이 이전 방식의 리팩토링 방법이었다. 

 

여기서 get은 외부에서 읽어갈때 다 get이다. 

외부에 있는것만 접근이 가능하다. 

Set은 값을 써주는애이다. 

 

말그래도 외부에서 읽기나 쓰기만 가능하도록 제어가 가능하다는 것이다. Set이 없어지면 읽기 전용이 된다는뜻이다.

null이면은 에러 메시지 쪽에 먼가를 남겨놀것이고

아니라면 값을 넣어줄것이다.

결론은 _strItem에 선택된 물건이 먼지 들어갈것이다.

 

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace _15_Partial
{
    /// <summary>
    /// 물건 종류 및 값을 가지고 있는 Enum Data
    /// </summary>
    public enum EnumItem
    {
        고기 = 10000,
        과자 = 3000,
        계란 = 5000,
        물 = 800,
        라면 = 3500,
        즉석식품 = 6500,
        냉동식품 = 8500,
    }

    /// <summary>
    /// 할인율을 가지고 있는 EnumData
    /// </summary>
    public enum EnumRate
    {
        할인_3 = 3,
        할인_5 = 5,
        할인_10 = 10,
        할인_20 = 20,
        사장할인_80 = 80,
    }
    

    //Enum을 class 외부에서 사용하기 때문에 .cs File의 이름은 의미가 없음
    //class EnumClass
    //{
    //}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace _15_Partial
{
    /// <summary>
    /// 변수
    /// </summary>
    partial class cData
    {
        private double _dTotalPrice = 0.0;
        public double DTotalPrice
        {
            get => _dTotalPrice;
            set
            {
                _dTotalPrice = _dTotalPrice + value;  // 외부에서 값을 입력 할 경우 기존 값에 값을 더해서 내부변수에 저장
            }
        }


        private string _strItem = string.Empty;
        public string StrItem
        {
            // get을 막아 놓았기 때문에 외부에서 읽을 수 없음

            //get
            //{
            //    return _strItem;
            //}
            set
            {
                if (String.IsNullOrEmpty(value))  // 값이 들어 올 경우 정합성 확인 후 사용
                {
                    _strErrorName = "물건이 선택되지 않았습니다.";
                }
                else
                {
                    _strItem = value;
                }
            }
        }

        
        private int _iRate = 0;
        public int IRate
        {
            //get => _iRate;
            set
            {
                if (value > 20)   // 값이 들어 올 경우 정합성 확인 후 사용
                {
                    _strErrorName = "사장님만 가능 한 할인 입니다.";
                }
                else
                {
                    _iRate = value;
                }
            }
        }

        
        private int _iCount = 0;
        public int ICount
        {
            //get => _iCount;
            set
            {
                if (value > 5)   // 값이 들어 올 경우 정합성 확인 후 사용
                {
                    _strErrorName = "개별 물품은 5개이상 살수 없습니다.";
                }
                else if (value == 0)
                {
                    _strErrorName = "물품의 개수가 0개 입니다.";
                }
                else
                {
                    _iCount = value;
                }
            }
        }
        
        private string _strErrorName = string.Empty;
        public string StrErrorName
        {
            get => _strErrorName;
            //set => _strErrorName = value;    // Set을 사용하지 않기 때문에 외부에서 입력 불가
        }
       
    }

    /// <summary>
    /// 수식 계산
    /// </summary>
    partial class cData
    {
        /// <summary>
        /// 가지고 있는 내부 값들을 가지고 할인된 가격을 반환
        /// </summary>
        /// <returns></returns>
        public double fItemPrice()
        {
            double dPrice = 0;

            int iItemPrice = 0;

            if (String.IsNullOrEmpty(_strErrorName))  // Error 가 없으면 정상 값들을 받았다
            {
                iItemPrice = (int)Enum.Parse(typeof(EnumItem), _strItem);

                dPrice = iItemPrice - Math.Round((double)iItemPrice * (double)_iRate / 100, 2);
            }

            return dPrice * _iCount;
        }
    }

    /// <summary>
    /// 문자열
    /// </summary>
    partial class cData
    {
        /// <summary>
        /// 화면에 값을 보여주기 위해서 문자열을 생성
        /// </summary>
        /// <param name="dPrice"></param>
        /// <returns></returns>
        public string fResult(double dPrice)
        {
            if (_iRate == 0)
            {
                return string.Format("{0} X {1} : {2}원", _strItem, _iCount, dPrice);
            }
            else
            {
                return string.Format("{0} X {1} : {2}원 (할인율 : {3}%)", _strItem, _iCount, dPrice, _iRate);
            }
        }

        /// <summary>
        /// 내부 변수값들을 초기화 시킴 (외부에서 초기화를 못시키도록 만들어 놓았기 때문에 초기화 하는 함수를 만들어서 사용)
        /// </summary>
        public void fDataResult()
        {
            _strErrorName = string.Empty;
            _strItem = string.Empty;
            _iRate = 0;
            _iCount = 0;
        }
    }
    
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace _15_Partial
{
    public partial class Form1 : Form
    {
        cData _Data = new cData();  // cData라는 Glass를 사용 할 수 있도록 선업하고 초기화 하였습니다. (이번 강의 핵심 Class)

        /// <summary>
        /// 프로그램의 진입점 입니다.
        /// </summary>
        public Form1()
        {
            InitializeComponent();
        }


        /// <summary>
        /// Form1을 Load 하는 시점에 ComboBox에 Data를 넣어 줍니다. (EnumClass.cs에 Enum 관련 된 내용들을 정리 하고 가지고와서 사용 하였습니다.)
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Form1_Load(object sender, EventArgs e)
        {
            EnumItem[] ei = (EnumItem[])Enum.GetValues(typeof(EnumItem));  // Enum에 있는 값들을 배열 형태로 불러옵니다. (Enum을 많이 쓰시면 자주 사용 됩니다.)

            foreach (EnumItem oitem in ei)  //foreach 문으로 Enum 형태의 배열에 있는 값을 하나씩 가져와서 ComboBox에 넣어 줍니다.
            {
                cboxItem.Items.Add(oitem.ToString());
            }
            
            foreach (EnumRate oitem in (EnumRate[])Enum.GetValues(typeof(EnumRate)))   // 위와 같음
            {
                cboxRate.Items.Add(oitem.ToString());
            }
        }

        /// <summary>
        /// Button "담기"를 Click 하였을 경우 cData Class에 Form에 Setting 된 값을 넣어주고 계산을 한뒤 값을 ListBox에 보여 줍니다.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnAdd_Click(object sender, EventArgs e)
        {
            _Data.fDataResult();  // cData에 있는 변수 값들을 초기화 시킴

            _Data.StrItem = cboxItem.Text;
            _Data.IRate = (int)Enum.Parse(typeof(EnumRate), cboxRate.Text);  // 문자 형태로 가지고 있는 Enum 값을 int 형태로 변환 시킴 (Enum을 많이 쓰시면 자주 사용 됩니다.)
            _Data.ICount = (int)numCout.Value;

            if (!String.IsNullOrEmpty(_Data.StrErrorName))   // Error Data가 있을 경우 tboxErrorMsg에 Error 내용을 보여주고 종료
            {
                tboxErrorMsg.Text = _Data.StrErrorName;
                return;
            }

            //Error가 없을 경우 아래 할인 가격을 계산하는 Logic을 수행 후 ListBox에 값을 뿌려줌.

            double dPrice = _Data.fItemPrice();
            lboxItem.Items.Add(_Data.fResult(dPrice));

            _Data.DTotalPrice = dPrice;
            tboxResult.Text = _Data.DTotalPrice.ToString() + "원";
        }
    }
}