본문 바로가기
C#

[C#] 부분 클래스와 부분 메서드(partial), 정적 클래스(static)

by RucA 2024. 5. 2.
728x90
반응형

부분(분할) 클래스와 부분 메서드의 개념과 사용법을 직관적인 예제와 함께 간단히 정리해보겠다. 이후 정적 클래스의 개념과 특성을 알아본다.

 

부분(Partial) 클래스


분할 클래스라고도 부른다. 클래스의 기능이 복잡하면 하나의 클래스가 몹시 길어지기 때문에, 한 파일에 한 클래스를 구현하는 것이 어려울 수 있다. 닷넷 2.0부터 partial 키워드를 통해 한 클래스를 여러 파일로 분할할 수 있게 되었다. 부분 클래스 정의를 사용할 때의 제한 사항에 주의.

 

  • 부분 클래스 : 여러 파일로 나눠서 동일 클래스 구성하기  
//1. First.cs
using System;

namespace PartialPractice
{
    public partial class PartialClass
    {
        public void pFirst() => Console.WriteLine("Partial First");
    }
}

//2. Second.cs
using System;

namespace PartialPractice
{
    public partial class PartialClass
    {
        public void pSecond() => Console.WriteLine("Partial Second");
    }
}

//3. Main.cs
namespace PartialPractice
{
    public partial class PartialClass
    {
        static void Main()
        {
            var pSum = new PartialClass();
            pSum.pFirst();
            pSum.pSecond();
        }
    }
}

 

  • 부분 클래스 : 속성과 메서드를 나눠서 동일 클래스 구성하기
using System;

//속성만 정의한 부분 클래스
public partial class PartialStudent
{
    public string Name { get; set; }
    public int ID { get; set; } 
}
    
//메서드만 정의한 부분 클래스 : 다른 부분 클래스의 멤버 사용 가능
public partial class PartialStudent
{
    public void PrintInfo() => Console.WriteLine($"{Name}[{ID}]");
}

class MainClass
{
    static void Main()
    {
        PartialStudent s = new PartialStudent() { Name = "김밥", ID = 01111 };
        s.PrintInfo();
    }
}

 

  • 제한 사항 : 부분 클래스 정의를 사용할 때의 규칙들
    • 한 클래스를 구성하는 모든 부분 클래스(부분 형식)들은 모두 partial 한정자를 통해 정의되어야 한다.
    • partial 한정자는 class, struct, interface 바로 앞에 나타날 수 있다.
    • 부분 형식 정의 내에 중첩해서 부분 형식을 사용할 수 있다.
    • 동일한 형식의 일부로 작성된 모든 부분 형식 정의는 동일한 어셈블리와 동일한 모듈(.exe와 .dll)에서 정의된다.
    • 모든 부분 형식 정의에서 클래스 이름 및 제네릭 형식의 매개 변수(순서 포함)가 일치해야 한다.
    • 한 부분 형식 정의에 다음과 같은 키워드 등이 있는 경우, 다른 부분 형식 정의의 키워드와 충돌 불가하다.
      • public
      • private
      • protected
      • internal
      • abstract
      • sealed
      • 제네릭 제약 조건
      • 기본 클래스
      • new 한정자(중첩)

 

 

부분(Partial) 메서드


부분 클래스(또는 구조체)는 부분 메서드를 포함할 수 있다. 마찬가지로 partial 키워드를 통해 사용한다. 주로 한 부분은 메서드의 시그니처(메서드 이름, 매개 변수의 형식 및 개수 등 메서드의 정체성)를 정의하고, 다른 한 부분은 메서드를 구현하는 방식으로 이루어진다.  부분 클래스 정의를 사용할 때의 제한 사항에 주의.

 

  • 부분 메서드 사용 예제
using System;

//속성
public partial class PartialStudent
{
    public string Name { get; set; }
    public int ID { get; set; } 
    public int Age { get; set; } 
}
    
//부분 메서드 시그니처 정의
public partial class PartialStudent
{
    public partial void PrintInfo();
    public partial void PrintInfoOne(int opt);
}

//부분 메서드 구현
public partial class PartialStudent
{
    public partial void PrintInfo() => Console.WriteLine($"{Name}[{Age}] = {ID}");

    public partial void PrintInfoOne(int opt)
    {
        if (opt == 0)
        {
            Console.WriteLine($"{Name}");
        }
        else if (opt == 1)
        {
            Console.WriteLine($"{Age}");
        }
        else
        {
            Console.WriteLine($"{ID}");
        }
    }

}

class MainClass
{
    static void Main()
    {
        PartialStudent s = new PartialStudent() { Name = "김밥", ID = 01111, Age=25 };
        s.PrintInfo();
        s.PrintInfoOne(0);
        s.PrintInfoOne(1);
        s.PrintInfoOne(2);
    }
}

 

  • 제한 사항 : 부분 메서드 정의를 사용할 때의 규칙들
    • 모두 partial 한정자를 통해 정의되어야 한다.
    • 부분 메서드들의 시그니처가 일치해야 한다.
    • 부분 메서드는 static 및 unsafe 한정자를 사용할 수 없다.
    • 부분 메서드는 제네릭일 수 있다.
    • 다음 상황에서는 partial 키워드가 허용되지 않는다.
      • 생성자
      • 소멸자
      • 오버로드된 연산자
      • 속성 선언
      • 이벤트 선언
    • 다음 상황에서는 메서드의 구현이 강제되지 않는다.
      • 접근성 한정자(기본 private 포함)가 없는 경우
      • void 반환하는 경우
      • out 매개 변수가 없는 경우
      • 한정자 virtual, override, sealed, new, extern이 없는 경우
      • 대리자를 정의하지 않은 경우
    • 위의 경우가 아니라면 메서드의 구현이 강제된다.

 

 

정적(Static) 클래스


static 키워드를 붙여 사용한다. 기본적으로 비정적 클래스와 동일하지만, 인스턴스화할 수 없다는 한 가지 차이점이 있다. 주로 인스턴스를 만들지 않고 여러 곳에서 활용되는 경우 사용한다. 내부 구조를 모르더라도 입력 매개 변수에 대해서만 작동하도록 유도해 편의성을 높일 수 있다. System.Math와 같은 닷넷 클래스 라이브러리는 정적 클래스이다.

 

  • 정적 클래스의 특징
    • static 키워드를 붙인다.
    • static 멤버만 가진다.
    • 인스턴스화될 수 없다(new 연산자 사용 불가). 
    • 인스턴스 생성자를 포함할 수 없다.
    • 유틸리티 클래스 용도로 사용된다.
  • 정적 클래스 예제
//공식 문서 코드
public static class TemperatureConverter
{
    public static double CelsiusToFahrenheit(string temperatureCelsius)
    {
        // Convert argument to double for calculations.
        double celsius = Double.Parse(temperatureCelsius);

        // Convert Celsius to Fahrenheit.
        double fahrenheit = (celsius * 9 / 5) + 32;

        return fahrenheit;
    }

    public static double FahrenheitToCelsius(string temperatureFahrenheit)
    {
        // Convert argument to double for calculations.
        double fahrenheit = Double.Parse(temperatureFahrenheit);

        // Convert Fahrenheit to Celsius.
        double celsius = (fahrenheit - 32) * 5 / 9;

        return celsius;
    }
}

class TestTemperatureConverter
{
    static void Main()
    {
        Console.WriteLine("Please select the convertor direction");
        Console.WriteLine("1. From Celsius to Fahrenheit.");
        Console.WriteLine("2. From Fahrenheit to Celsius.");
        Console.Write(":");

        string? selection = Console.ReadLine();
        double F, C = 0;

        switch (selection)
        {
            case "1":
                Console.Write("Please enter the Celsius temperature: ");
                F = TemperatureConverter.CelsiusToFahrenheit(Console.ReadLine() ?? "0");
                Console.WriteLine("Temperature in Fahrenheit: {0:F2}", F);
                break;

            case "2":
                Console.Write("Please enter the Fahrenheit temperature: ");
                C = TemperatureConverter.FahrenheitToCelsius(Console.ReadLine() ?? "0");
                Console.WriteLine("Temperature in Celsius: {0:F2}", C);
                break;

            default:
                Console.WriteLine("Please select a convertor.");
                break;
        }

        // Keep the console window open in debug mode.
        Console.WriteLine("Press any key to exit.");
        Console.ReadKey();
    }
}

 

정적 클래스와 유사하게 활용되지만, 자체 인스턴스 하나만 생성되도록 하는 비정적 클래스를 싱글톤(Singleton)이라고 한다. 이는 이후에 유니티를 진행하며 더 구체적으로 다루겠다.

728x90
반응형