왜 부분 클래스를 사용합니까?


72

내 이해에서 partial키워드는 아무것도하지 않고 클래스를 여러 소스 파일로 나눌 수 있습니다. 코드 구성 이외의 다른 이유가 있습니까? 생성 된 UI 클래스에서 사용되는 것을 보았습니다.

전체 키워드를 작성하는 것은 좋지 않은 이유입니다. 클래스가 여러 파일을 요구할만큼 충분히 큰 경우에는 너무 많은 작업을 수행했을 수 있습니다. 다른 프로그래머가 완성 할 클래스를 부분적으로 정의하는 데 사용할 수 있다고 생각했지만 추상 클래스를 만드는 것이 좋습니다.


10
실제로 "전체 키워드"도 아닙니다. 그것은의 문맥 키워드 . partial그것은 전에 올 때만 의미합니다 class. 코드의 다른 부분 등에서 식별자 이름으로 사용할 수 있습니다.
Dean Harding

4
당신이 그들을 사용하고 생성 된 코드가 아닌 경우, 나는 당신을 싫어합니다. 당신은 개인적으로가 아니라 일반적으로 당신입니다. 부분 클래스를 통한 코드 다운을 싫어합니다.
Steven Evers

3
"코드 찾기"는 어렵지 않습니다. 모든 클래스 메서드는보고있는 부분의 어느 부분에 관계없이 VS의 드롭 다운에 여전히 나타납니다. 다른 코드 탐색도 잘 작동합니다 ( "영리한"R # 스타일 탐색 또는 좋은 오래된 shift-ctrl-f
Steve

2
부분 클래스가 별도의 파일에 있어야한다는 것은 오해입니다.
Bart

답변:


110

생성 된 클래스를 상속하지 않고 생성 된 코드에 사용자 정의 로직을 추가 할 수 있기 때문에 일부 사용자 정의 도구로 클래스의 한 부분이 생성되는 모든 시나리오에서 매우 유용합니다. Btw. 같은 이유로 부분적인 방법도 있습니다.

UI뿐만 아니라 Linq-To-Sql 또는 Entity Framework와 같은 다른 기술도 이것을 많이 사용합니다.


44
또한 생성 된 코드를 버전 제어에서 제외하고 코드를 버전 제어 상태로 유지할 수 있습니다.
Frank Shearar

3
좋은 지적, 나는 그런 생각을 한 적이 없습니다. 그래도 실제로 악용되는 것을 보았습니다. (불량한) 프로그래머가 파일 크기를 관리 할 수있는 방법.
Martin Wickman

1
내가 사용한 가장 좋은 예는 다음과 같습니다. a) Linq에서 클래스를 확장하려는 SQL 데이터 컨텍스트로; b) 웹 서비스에서 전달 된 클래스를 확장합니다. 어느 경우에도 이것이 남용이 아니며 파일 크기를 관리 할 수있는 수단으로 유지하는 수단도 아닙니다. 그런 식으로 사용 된 것을보고 매우
기쁠

3
WinForm 클래스는 컨트롤을 생성하는 모든 디자이너 코드를 숨기는 데 사용합니다 (특히 디자이너가 생성하는 모든 코드를 무작위로 재정렬하여 diff / blaming 할 때 큰 혼란을 초래하기 때문에). XML로 작업하는 경우 XSD 도구는 스키마 파일에서 부분 클래스를 다시 작성하여 코드를 자동 생성 정렬과 분리 할 수 ​​있습니다.
Dan Neely

2
@MartinWickman이 반드시 눈에 띄는 것은 아닙니다. 레거시 코드에서 God 객체를 리팩토링하기에 좋은 출발점입니다. 먼저 큰 클래스를 별도의 파일로 분할하여 조경을 정리하십시오. (나는 당신의 의견이 매우 오래된 것을 알고 있습니다)
Konrad Morawski

26

당신이 말했듯이, 그것은 종종 생성 된 코드를 분리하는 데 사용됩니다. 클래스 / 파일의 크기와는 관련이없는 경우가 많습니다.

생성 된 코드 분리의 이점은 스타일 중 하나입니다. 생성 된 코드는보기 흉하고 읽을 수 없으며 많은 코딩 표준 (및 StyleCop 검사)에 실패 할 수 있지만, 아무 것도 읽거나 직접 유지 관리 할 필요는 없습니다. 따라서 다른 파일에서 "숨겨"면 나머지 클래스가 표준에 맞는지, StyleCop 검사 등을 통과시키는 데 집중할 수 있습니다.

내가 사용한 또 다른 영역은 클래스가 여러 인터페이스를 구현하는 곳입니다. 구현은 별도의 파일로 분리하는 것이 좋을 수 있습니다. 개인 취향의 문제이지만 더 많은 코딩 표준이 필요하지는 않습니다. 또는 예방하십시오).


9
인터페이스 구현을 분리하기 위해 클래스 부분을 사용하는 것을 결코 생각하지 못했습니다. 이는 훌륭한 아이디어입니다.
Mark Booth

그것은 스타일 이상의 것입니다. 코드 생성기의 개발자는 생성기가 관리하는 파일에서 코드를 편집 할 수 있도록 후프를 뛰어 넘어야하며 문제가 발생할 수도 있습니다. 나에게있어 # 1의 장점은 생성기가 만질 수있는 코드를 작성할 수있는 공간을 제공한다는 것입니다. 이것은 실질적인 이점입니다.
Daniel

19

내가 일하는 개발자 중 한 사람은 몇 주 전에 통제 불능 상태이고 많은 공개 방법이있는 거대한 신 클래스를 리팩토링하는 데 꽤 잘 사용했습니다. 각 비트의 논리적 기능을 분리하여 클래스를 별도의 부분 클래스로 만들면 기존 기능을 손상시키지 않고 클래스가되어야하는 더 많은 원자 단위로 클래스를 물리적으로 분리하여 공통 사항과 그렇지 않은 부분을 볼 수 있습니다. 이를 첫 번째 단계로 사용하면 부분을 자체 독립 클래스로 더 쉽게 분류하여 코드 기반 전체에서 구현할 수 있습니다. 나는 이것이 좋은 생각이라고 생각했다.

그러나 일반적으로 새 코드를 작성할 때 기계 생성 클래스를 보강하는 데만 사용해야한다고 생각합니다.


1
그게 얼마나 유용한 지 알 수 있습니다. 그것이 언어로되어 있는지에 대한 정당성 여부는 모르겠습니다 ... 모릅니다. 그러나 기계 생성 코드는 또 다른 이야기입니다.
Michael K

2
그렇습니다. 언어에 대한 것이 타당하지는 않지만 사용하는 재미있는 방법입니다.

18

부분적인 부분이 이해되는 몇 가지 유용한 시나리오를 생각할 수 있습니다. 대부분은 내 프로젝트에서 자신을 사용하고 있습니다.

  • 분리하려면 도구 / IDE / 디자이너 당신은 유지하고 코드에서 코드를 생성합니다. 좋은 예로 Form.Designer.csWindows Forms 응용 프로그램을위한 디자이너 생성 코드가 들어 있는 파일이 있습니다. 다른 많은 .NET 형식에는 일부 도구 생성 코드가있어 프로젝트를 빌드 할 때 잠재적으로 재생성 될 수 있으므로 모든 사용자 지정 변경 내용이 제거됩니다. 분리는 코드 및 변경 사항을 자동 수정으로부터 안전하게 유지하는 데 도움이됩니다.

  • 구현시 많은 코드로 여러 인터페이스 를 구현할 때 . 각 인터페이스마다 별도의 부분 파일을 사용하는 경향이 있습니다 {Class}.{Interface}.cs. IDE에서 {Class}구현하는 방법과 방법을 쉽게 알 수 있습니다.

  • 클래스에 하나 이상의 중첩 클래스가 포함되어 있어야하는 경우 , 특히 별도의 파일에 넣을 수있을만큼 충분한 코드가 있어야합니다. 위의 패턴을 고수하고 {Class}.{NestedClass}.cs각 중첩 클래스에 대해 명명 규칙을 사용합니다 . Virtlink의 답변에 이미 유사한 관행이 언급되어 있습니다.

  • 확장 메소드static 를 보유 할 클래스를 작성할 때 . 예를 들어 일반 및 비 제네릭 컬렉션과 같은 유사한 클래스 또는 인터페이스에 동일한 확장 메서드 논리를 제공하는 경우가 종종 있습니다 . 단일 클래스 또는 인터페이스에 대한 모든 확장 메서드를 정적 클래스의 별도 부분에 넣었습니다. 예를 들어, 인터페이스에 대한 모든 확장 방법을 한 곳에서 사용하고 다른 파일에서 와 동일한 방법을 사용 합니다. 또 다른 접근법은 매개 변수에 대해 가능한 모든 클래스를 사용하여 동일한 부분 (모든 과부하)을 동일한 부분에 배치하는 것입니다.ReverseIListIList<T>thisReverse하나의 파일로 구현. 코드 볼륨 측면에서 어느 것이 분리를 더 정당화 할 것인지, 또는 귀하 또는 귀하의 조직이 고수하고있는 일부 내부 규칙에 따라 다릅니다.

  • 나는 이것을 사용하지 않지만 여기서 설명 할 접근법을 좋아하는 일부 C / C ++ 사람들을 보았습니다 : 부분 메소드 만 사용 하여 클래스에 대한 부분을 작성하십시오 . 이것은 인터페이스를 정의하고 메소드 선언을 구현에서 분리하는 C / C ++ 방식과 유사합니다.

  • 순전히 논리적 관심사에 의한 분리 . 둘 이상의 논리 연산 세트를 자체적으로 결합하는 큰 클래스로 작업하는 경우 각 논리 관련 코드를 별도의 부분으로 분리 할 수 ​​있습니다. 일반적으로 이러한 클래스의 존재는 우려 분리 원칙에 위배되지만, 특히 오래된 코드베이스의 경우 실제 사례가 종종 관찰됩니다. 동료 사용자 Steve Evers는 이 질문대한 답변 에서 그들을 신 객체 라는 이름으로 언급하여 언급했습니다.. 나는 개인적으로 부분 클래스 접근 방식을 사용하여 작업을 쉽게하고 리팩토링을보다 투명하게 만들기 위해 실제로 큰 파일의 리팩토링이 발생하기 전에 코드를 분할했습니다. 또한 SVN과 같은 버전 관리 시스템을 사용할 때 발생할 수있는 충돌이 줄어 듭니다.


14

나는 누군가가 언급 한 것을 보지 못했습니다 : partial중첩 된 클래스를 자신의 파일에 넣는 데 사용 합니다.

모든 코드 파일에는 하나의 클래스, 구조체, 인터페이스 또는 열거 형 만 포함됩니다. 파일 이름에 찾고있는 것의 이름이 표시 될 때 객체에 대한 정의를 훨씬 쉽게 찾을 수 있습니다. Visual Studio는 프로젝트 폴더를 네임 스페이스와 일치 시키려고하므로 파일 이름이 클래스와 일치해야합니다.

이것은 또한 NestedClass중첩 된 클래스 MyClass가 내 프로젝트에 자체 파일을 가지고 있음을 의미합니다 MyClass.NestedClass.cs.

partial class MyClass
{
    private class NestedClass
    {
        // ...
    }
}

1
왜이 답변을 다운 투표했는지 궁금합니다. 언급 된 관행은 반 패턴이 아니며 내가 아는 문제를 유발하지 않습니다.
Ivaylo Slavov

1
또한 클래스 파일을 작게 (코드 줄로) 유지하면서 내부 클래스에 속하는 코드를 올바르게 캡슐화하는 문제를 해결합니다.
redcalx

10

생성 된 코드를 사용하여 제외하고, 내가 가진 유일한 적 그들에 대한 은폐하기위한 노력의 일환으로 사용되는 볼 수 신 객체 . 새로운 코드베이스를 이해하거나 동일한 객체 인 여러 소스 파일을 탐색하는 것은 매우 성가신 일입니다.

그래서 Why use partial classes?당신이 대답 할 때 : 생성 된 코드를 사용하지 않는 한,하지 마십시오.


+1. 이러한 유형의 개체가 이름 (신 개체)이라고하는 것은 처음이며 공식적인 것입니다. 새로운 것을 배우기에는 결코 늦지 않습니다.
Ivaylo Slavov

6

코드 구성이 유일한 이유이지만 처음에는 생각보다 깊어집니다. 부품이 생성되는 부분 클래스가있는 경우 다음을 쉽게 수행 할 수 있습니다.

  • 작성하는 클래스에서 수동 변경을 감지하지 않고 코드를 재생성하여 해당 부분을 덮어 쓰지 않도록합니다.
  • 테스트 범위, 소스 제어, 메트릭 등에서 생성 된 부분 클래스를 제외하십시오.
  • 상속 전략을 기반으로하지 않고 생성 된 코드를 사용하십시오 (여전히 다른 클래스에서 상속받을 수 있음).

1

또한 생성 / 암시 된 클래스가 부분적으로 선언 된 곳이 몇 개 있으므로 개발자가 클래스를 확장해야하는 경우 모든 곳에서 상속 및 재정의를 망칠 필요없이 전체 액세스 권한을 갖습니다. IIS에서 웹 양식 사이트를 처음 실행 한 후 일부 예제를 찾으려면 asp.net 임시 영역에서 생성 된 클래스를보십시오.


1

나는 그들을 위해 더러운 사용을 생각할 수 있습니다.

공통 기능이 필요한 클래스가 있지만 그 기능을 그 위의 상속 체인에 주입하고 싶지 않다고 가정하십시오. 또는 공통 헬퍼 클래스를 사용하는 클래스 세트가 있습니다.

기본적으로 다중 상속을 원하지만 C #은 비슷하지 않습니다. 그래서 당신이하는 일은 부분적으로 C / C ++에서 #include를 만드는 것입니다;

모든 기능을 클래스에 넣거나 헬퍼 클래스를 사용하십시오. 그런 다음 도우미 X를 복사하고 이름을 부분 클래스 A, B, C로 바꿉니다. A, B, C 클래스에 부분적으로 배치하십시오.

면책 조항 : 예, 이것은 악입니다. 다른 사람들이 당신에게 화를내는 경우에는 절대로 그렇게하지 마십시오.


믹스 인. 이것은 수동 복사를 피하기 위해 T4와 결합 될 수 있습니다.
Peter Taylor

언급 한 바와 같이, 이것은 믹스 인과 매우 유사합니다. 그러나 "특성"이라는 개념에 접근하고 있으며 달성하려는 목표를 안전하게 처리 할 있습니다. 나는에서 언어 무관 한 설명이 publius-ovidius.livejournal.com/314737.html 나는 C 번호 깨끗한 구현을 검토 한 결과,하지만 하나를 보지 못했다.
Ovid
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.