partial class 한 줄 정의partial class = “하나의 클래스를 여러 파일로 나눠서 정의할 수 있게 해주는 문법”
보통은 “클래스 하나 = 파일 하나”처럼 생각하기 쉬운데, C#에서는 하나의 클래스를 여러 .cs 파일에 나눠서 적을 수 있다.
나눠져 있는 코드들은 컴파일할 때 컴파일러가 전부 합쳐서 하나의 클래스로 만들어 준다.
예를 들어, 아래처럼 두 파일이 있다고 해 보자.
Person.cspublic partial class Person
{
public string Name { get; set; }
public void SayHello()
{
Console.WriteLine($"안녕, 나는 {Name}");
}
}
Person.Address.cspublic partial class Person
{
public string Address { get; set; }
public void PrintAddress()
{
Console.WriteLine($"주소: {Address}");
}
}
이 두 파일은 컴파일될 때 이렇게 하나의 Person 클래스로 합쳐진 것처럼 동작한다.
public class Person
{
public string Name { get; set; }
public void SayHello() { ... }
public string Address { get; set; }
public void PrintAddress() { ... }
}
개발자는 파일을 나눠서 관리하지만, 프로그램이 실행될 때는 그냥 한 클래스라고 생각하면 된다.
partial class를 쓰나?“그냥 한 파일에 다 쓰면 되지, 왜 쪼개서 쓰지?” 라는 생각이 들 수 있다. 대표적인 이유는 세 가지 정도다.
실무에서 가장 많이 쓰이는 이유는 바로 이거다.
예를 들어 WinForms에서 폼 하나를 만들면 이런 구조를 많이 보게 된다.
Form1.cs (내가 작성하는 코드)public partial class Form1 : Form
{
public Form1()
{
InitializeComponent(); // 디자이너가 만든 설정 코드 호출
}
private void button1_Click(object sender, EventArgs e)
{
MessageBox.Show("클릭!");
}
}
Form1.Designer.cs (디자이너가 자동 생성하는 코드)partial class Form1
{
private System.Windows.Forms.Button button1;
private void InitializeComponent()
{
this.button1 = new System.Windows.Forms.Button();
// 위치, 크기, 텍스트, 이벤트 핸들러 연결 등 자동 생성 코드
}
}
두 파일 모두 partial class Form1로 선언되어 있기 때문에, 둘이 합쳐져서 하나의 Form1 클래스가 된다.
이렇게 나누면 좋은 점:
.Designer.cs 파일을 자동으로 고쳐도, 내 코드가 섞이지 않는다.
어떤 클래스가 기능이 많아지면 줄 수가 엄청나게 길어질 수 있다. 예를 들어 OrderService에
등이 한꺼번에 들어 있으면 유지보수가 힘들다.
이럴 때 partial로 파일을 역할별로 나눌 수 있다.
OrderService.Query.cspublic partial class OrderService
{
public Order GetOrder(int id) { ... }
public List<Order> GetOrdersByCustomer(string customerCode) { ... }
}
OrderService.Command.cspublic partial class OrderService
{
public void CreateOrder(Order order) { ... }
public void CancelOrder(int id) { ... }
}
이런 식으로 나누면:
.Query.cs만 열면 됨.Command.cs만 보면 됨팀 작업을 할 때, 한 클래스에 기능이 몰려 있으면 한 파일에서 충돌이 많이 날 수 있다.
이런 상황에서 파일을 나눠 두면, 서로 다른 파일에서 작업할 수 있어서 충돌을 줄일 수 있다.
partial class의 규칙과 주의사항public partial class Person { ... }
public partial class Person { ... } // OK, 같은 클래스의 다른 부분
public partial class PersonEx { ... } // 이름이 다르면 완전히 다른 클래스
// 파일 1
namespace MyApp.Models
{
public partial class Person { ... }
}
// 파일 2
namespace MyApp.Models // 네임스페이스가 같아야 합쳐진다
{
public partial class Person { ... }
}
보통 한 파일에만 public partial class를 적고, 나머지는 partial class만 적어도 컴파일은 잘 된다.
하지만 가독성 측면에서는 가능하면 같은 접근제한자로 맞춰주는 편이 좋다.
중요한 포인트는, partial은 어디까지나 “코드 작성 편의를 위한 문법”이라는 점이다.
Person 클래스만 존재한다.실제로 partial class가 어떻게 동작하는지, 아주 간단한 예제로 확인해 보자.
Person.Basic.cspublic partial class Person
{
public string Name { get; set; }
public int Age { get; set; }
public void PrintBasicInfo()
{
Console.WriteLine($"이름: {Name}, 나이: {Age}");
}
}
Person.Job.cspublic partial class Person
{
public string JobTitle { get; set; }
public void PrintJobInfo()
{
Console.WriteLine($"직업: {JobTitle}");
}
}
Program.csusing System;
class Program
{
static void Main()
{
Person p = new Person();
p.Name = "홍길동";
p.Age = 30;
p.JobTitle = "개발자";
p.PrintBasicInfo(); // 이름, 나이 출력
p.PrintJobInfo(); // 직업 출력
Console.ReadKey();
}
}
비록 파일은 3개로 나눠져 있지만, 실제로는 그냥 Person이라는 클래스 한 개가 있는 것처럼 자연스럽게 동작한다.
partial class 안에서는 partial method도 쓸 수 있다.
이건 자동 생성 코드와 후처리 코드를 나눌 때 유용하다.
public partial class Person
{
partial void OnCreated();
public Person()
{
OnCreated(); // 구현이 있으면 호출, 없으면 컴파일 시 제거됨
}
}
public partial class Person
{
partial void OnCreated()
{
Console.WriteLine("Person 객체가 생성되었습니다.");
}
}
구현을 해 두면 생성자에서 자동으로 호출되고,
구현을 안 하면 컴파일러가 그냥 이 호출 자체를 지워 버린다.
이건 조금 고급 기능에 가까우니까, “partial class 안에 partial method라는 것도 있다” 정도만 알고 넘어가도 충분하다.
앞으로 프로젝트에서 Form1.Designer.cs, SomeWindow.g.cs 같은 파일을 보게 되면,
“아, 이게 바로 partial class로 나눠진 자동 생성 코드구나” 하고 이해하면 된다.