답변:
부분 클래스의 가장 큰 사용은 코드 생성기 / 디자이너의 삶을 더 쉽게 만드는 것입니다. 부분 클래스를 사용하면 생성기가 생성해야하는 코드를 간단히 방출 할 수 있으며 파일에 대한 사용자 편집을 처리 할 필요가 없습니다. 마찬가지로 사용자는 두 번째 부분 클래스를 사용하여 새 멤버로 클래스에 주석을 달 수 있습니다. 이것은 관심사 분리를위한 매우 깨끗한 프레임 워크를 제공합니다.
그것을 보는 더 좋은 방법은 디자이너가 부분 수업 전에 어떻게 기능했는지를 보는 것입니다. WinForms 디자이너는 코드를 수정하지 않는 것에 대한 강력한 말로 지역 내부의 모든 코드를 뱉어냅니다. 나중에 처리하기 위해 생성 된 코드를 찾기 위해 모든 종류의 휴리스틱을 삽입해야했습니다. 이제 designer.cs 파일을 열고 디자이너와 관련된 코드 만 포함하고 있다는 확신을 가질 수 있습니다.
다른 용도는 다른 인터페이스의 구현을 분할하는 것입니다. 예 :
partial class MyClass : IF1, IF2, IF3
{
// main implementation of MyClass
}
partial class MyClass
{
// implementation of IF1
}
partial class MyClass
{
// implementation of IF2
}
Implements
키워드를 사용하여 메소드가 인터페이스에 속한다는 것을 나타냅니다)
다른 답변 외에도 ...
나는 신 클래스를 리팩토링하는 데 디딤돌로 도움이된다는 것을 알았습니다. 클래스에 여러 책임이있는 경우 (특히 매우 큰 코드 파일 인 경우) 코드를 구성하고 리팩토링하기위한 첫 번째 패스로 1x 부분 클래스 당 책임을 추가하는 것이 좋습니다.
실제로 실행 동작에 영향을 미치지 않고 코드를 훨씬 더 읽기 쉽게 만들 수 있기 때문에 크게 도움이됩니다. 또한 책임을 쉽게 리팩토링하거나 다른 측면과 밀접하게 관련되어있는시기를 식별하는 데 도움이 될 수 있습니다.
그러나, 분명히 – 이것은 여전히 나쁜 코드입니다. 개발이 끝날 때 여전히 클래스 당 하나의 책임을 원합니다 ( 부분 클래스가 아닌 ). 그것은 단지 디딤돌입니다 :)
부분 메소드 선언 만 코드는 메소드 선언으로 만 컴파일되며 메소드 구현이 존재하지 않는 경우 컴파일러는 해당 코드를 안전하게 제거 할 수 있으며 컴파일 시간 오류가 발생하지 않습니다.
포인트 4를 확인하려면 : winform 프로젝트를 작성하고 Form1 생성자 다음에이 행을 포함시키고 코드를 컴파일하십시오.
partial void Ontest(string s);
다음은 부분 클래스를 구현할 때 고려해야 할 사항입니다.
한 가지 유용한 용도는 생성 된 코드를 동일한 클래스에 속하는 수작업 코드와 분리하는 것입니다.
예를 들어 LINQ to SQL은 부분 클래스를 사용하므로 다 대다 관계와 같은 특정 기능 부분을 직접 구현할 수 있으며 코드를 다시 생성 할 때 해당 사용자 지정 코드 부분을 덮어 쓰지 않습니다.
WinForms 코드도 마찬가지입니다. 모든 Designer 생성 코드는 일반적으로 손대지 않는 하나의 파일로 들어갑니다. 직접 작성한 코드는 다른 파일로 들어갑니다. 이렇게하면 Designer에서 무언가를 변경할 때 변경 사항이 사라지지 않습니다.
Partial Class가 자동 코드 생성에 사용되는 것은 사실이며, 한 번의 사용으로 수천 줄의 코드를 가진 큰 클래스 파일을 유지할 수 있습니다. 수업이 10 만 줄로 끝나는 것을 결코 알지 못하고 다른 이름으로 새 수업을 만들고 싶지 않습니다.
public partial class Product
{
// 50 business logic embedded in methods and properties..
}
public partial class Product
{
// another 50 business logic embedded in methods and properties..
}
//finally compile with product.class file.
또 다른 가능한 용도는 둘 이상의 개발자가 서로 다른 장소에 저장된 동일한 클래스에서 작업 할 수 있다는 것입니다. 사람들은 웃을 지 모르지만 때로는 소수 일 수 있다는 것을 결코 알지 못합니다.
public partial class Product
{
//you are writing the business logic for fast moving product
}
public partial class Product
{
// Another developer writing some business logic...
}
이해가 되길 바랍니다!
부분 클래스는 여러 파일에 걸쳐 있습니다.
C # 클래스 선언에서 부분 수정자를 어떻게 사용할 수 있습니까?
부분 클래스를 사용하면 클래스를 여러 파일로 물리적으로 분리 할 수 있습니다. 이것은 종종 코드 생성기에 의해 수행됩니다.
예
일반 C # 클래스를 사용하면 동일한 프로젝트에서 두 개의 개별 파일로 클래스를 선언 할 수 없습니다. 그러나 partial
수정자를 사용하면 가능합니다.
한 파일을 일반적으로 편집하고 다른 파일을 시스템에서 생성하거나 거의 편집하지 않는 경우에 유용합니다.
다음은 명확히하는 예입니다.
class Program
{
static void Main()
{
A.A1();
A.A2();
}
}
파일 A1.cs의 내용 : C #
using System;
partial class A
{
public static void A1()
{
Console.WriteLine("A1");
}
}
파일 A2.cs의 내용 : C #
using System;
partial class A
{
public static void A2()
{
Console.WriteLine("A2");
}
}
산출:
A1
A2
여기에 부분이 필요합니다.
partial
수정자를 제거하면 이 텍스트를 포함하는 오류가 발생합니다.
[네임 스페이스 '
<global namespace>
'에는 이미 ' '에 대한 정의가 포함되어 있습니다A
.
팁:
이 문제를 해결하려면 partial
키워드 를 사용 하거나 클래스 이름 중 하나를 변경하십시오.
C # 컴파일러는 부분 클래스를 어떻게 처리합니까?
IL 디스어셈블러를 사용하여 위 프로그램을 분해하면 A1.cs 및 A2.cs 파일이 제거 된 것을 볼 수 있습니다. 클래스 A가 있음을 알 수 있습니다.
클래스 A는 동일한 코드 블록에 메소드 A1 및 A2를 포함합니다. 두 클래스는 하나로 통합되었습니다.
A1.cs 및 A2.cs의 컴파일 결과 : C #
internal class A
{
// Methods
public static void A1()
{
Console.WriteLine("A1");
}
public static void A2()
{
Console.WriteLine("A2");
}
}
요약
거대한 클래스를 사용하거나 팀에서 작업 할 때 가능한 모든 것을 최대한 깨끗하게 유지하십시오. 재정의하지 않고 편집하거나 항상 변경 내용을 커밋 할 수 있습니다
효과적인 리팩토링에 적합하지 않은 충분히 큰 클래스가있는 경우 클래스를 여러 파일로 분리하면 정리하는 데 도움이됩니다.
예를 들어 토론 포럼과 제품 시스템이 포함 된 사이트에 대한 데이터베이스가 있고 두 개의 다른 제공자 클래스를 작성하지 않으려는 경우 (프록시 클래스와 동일하지 않음) 명확하게 할 수 있습니다. 다른 파일에 단일 부분 클래스를 만듭니다.
MyProvider.cs-핵심 로직
MyProvider.Forum.cs-포럼과 관련된 메소드
MyProvider.Product.cs-제품 메소드
사물을 정리하는 또 다른 방법 일뿐입니다.
또한 다른 사람들이 말했듯이 다음에 클래스를 다시 생성 할 때 추가 내용이 손상 될 위험을 발생시키지 않고 생성 된 클래스에 메소드를 추가하는 유일한 방법입니다. 템플릿 생성 (T4) 코드, ORM 등에 유용합니다.
서비스 참조는 부분 클래스가 생성 된 코드를 사용자가 만든 코드와 분리하는 데 유용한 또 다른 예입니다.
서비스 참조를 업데이트 할 때 서비스 클래스를 덮어 쓰지 않고 "확장"할 수 있습니다.
내가 본 또 다른 용도는
데이터 액세스 로직에 관한 큰 추상 클래스 확장
Post.cs, Comment.cs, Pages.cs라는 이름의 다양한 파일이 있습니다 ...
in Post.cs
public partial class XMLDAO :BigAbstractClass
{
// CRUD methods of post..
}
in Comment.cs
public partial class XMLDAO :BigAbstractClass
{
// CRUD methods of comment..
}
in Pages.cs
public partial class XMLDAO :BigAbstractClass
{
// CRUD methods of Pages..
}
대부분의 사람들은 partial
은 생성 된 코드 파일이있는 클래스 또는 인터페이스에만 사용해야한다고 말합니다. 동의하지 않으며 여기에 이유가 있습니다.
하나의 예를 들어, 그건 ...는 C # System.Math 클래스에서의 모습을 보자 클래스 . 70 개 이상의 메서드를 모두 동일한 단일 코드 파일에 넣지 않습니다. 유지하는 것은 악몽 일 것입니다.
각 수학 방법을 개별 부분 클래스 파일에 배치하고 모든 코드 파일을 프로젝트의 Math 폴더에 배치하면 조직이 훨씬 깔끔해집니다.
다양한 기능을 가진 다른 많은 클래스에서도 마찬가지입니다. 예를 들어 PrivateProfile API를 관리하기위한 클래스는 단일 프로젝트 폴더에서 깨끗한 부분 클래스 파일 세트로 분할함으로써 이점을 얻을 수 있습니다.
개인적으로, 저는 대부분의 사람들이 "도우미"또는 "유틸리티"클래스를 각 메소드 또는 메소드 기능 그룹에 대한 개별 부분 파일로 분리합니다. 예를 들어 한 프로젝트에서 문자열 도우미 클래스에는 거의 50 개의 메서드가 있습니다. 그것은 심지어 지역을 사용하는 긴 다루기 힘든 코드 파일 일 것입니다. 각 방법마다 개별 부분 클래스 파일을 사용하여 유지 관리하는 것이 훨씬 쉽습니다.
부분 클래스를 사용하는 것을 조심 하고이 작업을 수행 할 때 프로젝트 전체에서 모든 코드 파일 레이아웃을 일관되게 유지하십시오. 클래스 공용 열거 형 및 클래스 전용 멤버를 폴더에있는 Common.cs 또는 유사한 이름의 파일에 배치하는 것과 같이 파일에 포함 된 부분 파일에만 한정되지 않는 한 파일 전체에 분산시키는 대신.
클래스를 별도의 파일로 분할하면 현재 파일의 서로 다른 두 섹션을 동시에 볼 수있는 텍스트 편집기 스플리터 막대를 사용할 수 없게됩니다.
부분 클래스를 사용하면 소스 파일을 추가하기 만하면 적절하게 설계된 프로그램에 기능을 추가 할 수 있습니다. 예를 들어, 파일 가져 오기 프로그램은 파일을 처리하는 모듈을 추가하여 다른 유형의 알려진 파일을 추가 할 수 있도록 설계 될 수 있습니다. 예를 들어, 주 파일 형식 변환기에는 작은 클래스가 포함될 수 있습니다.
부분 공개 클래스 zzFileConverterRegistrar 이벤트 등록 (ByVal mainConverter as zzFileConverter) 서브 레지스터 전체 (ByVal mainConverter as zzFileConverter) 이벤트 등록기 (mainConverter) 엔드 서브 엔드 클래스
하나 이상의 파일 변환기 유형을 등록하려는 각 모듈에는 다음과 같은 내용이 포함될 수 있습니다.
부분 공개 클래스 zzFileConverterRegistrar Private Sub RegisterGif (ByVal mainConverter as zzFileConverter)는 나를 등록합니다. mainConverter.RegisterConverter ( "GIF", GifConverter.NewFactory)) 엔드 서브 엔드 클래스
주 파일 변환기 클래스는 "노출"되지 않으며, 추가 기능 모듈이 연결할 수있는 작은 스텁 클래스 만 노출합니다. 이름 충돌이 약간의 위험이 있지만 각 추가 기능 모듈의 "등록"루틴이 처리하는 파일 유형에 따라 이름이 지정된 경우 문제가되지 않습니다. 그러한 것들이 걱정된다면 등록 서브 루틴의 이름으로 GUID를 붙일 수 있습니다.
편집 / 부록 분명히, 이것의 목적은 다양한 개별 수업이 주 프로그램이나 수업에 알릴 수있는 수단을 제공하는 것입니다. 기본 파일 변환기가 zzFileConverterRegistrar로 수행하는 유일한 작업은 하나의 인스턴스를 작성하고 RegisterAll 메소드를 호출하여 Register 이벤트를 발생시키는 것입니다. 해당 이벤트를 연결하려는 모든 모듈은 그에 대한 응답으로 임의의 코드를 실행할 수 있지만 (전체 아이디어) 모듈이 zzFileConverterRegistrar 클래스를 잘못 확장하여 다른 이름과 일치하는 메소드를 정의하는 것 외에 모듈이 수행 할 수있는 일은 없습니다 . 부적절하게 작성된 확장 프로그램이 부적절하게 작성된 확장 프로그램을 깨뜨리는 것이 가능할 수도 있지만, 그 해결책은 확장 프로그램을 깨뜨리기를 원하지 않는 사람이 간단하게 올바르게 작성하는 것입니다.
부분 클래스를 사용하지 않고 주 파일 변환기 클래스 내의 어딘가에 약간의 코드가있을 수 있습니다.
RegisterConverter ( "GIF", GifConvertor.NewFactory) RegisterConverter ( "BMP", BmpConvertor.NewFactory) RegisterConverter ( "JPEG", JpegConvertor.NewFactory)
그러나 다른 변환기 모듈을 추가하려면 변환기 코드의 해당 부분으로 이동하여 새 변환기를 목록에 추가해야합니다. 더 이상 필요하지 않은 부분 방법을 사용하면 모든 변환기가 자동으로 포함됩니다.
IModule
인터페이스를 구현하지 않는 이유는 무엇입니까?
IModule
사용하여 구현 된 클래스에 대해 컴파일 된 어셈블리를 스캔하고 MEF (많은 것 중 하나) 등과 같은 플러그인 프레임 워크를 사용할 수 있습니다.
부분 클래스는 최근에 여러 개발자가 파일의 동일한 부분에 새로운 메소드가 추가 된 (Resharper에 의해 자동화 된) 하나의 파일에 여러 개발자가 추가하는 소스 제어에 도움이되었습니다.
git에 대한 이러한 푸시로 인해 병합 충돌이 발생했습니다. 새 도구를 완전한 코드 블록으로 사용하도록 병합 도구에 지시하는 방법을 찾지 못했습니다.
이와 관련하여 부분 클래스를 사용하면 개발자가 파일 버전을 고수 할 수 있으며 나중에 다시 병합 할 수 있습니다.
예 -
에서 MSDN :
1. 컴파일 타임에 부분 유형 정의의 속성이 병합됩니다. 예를 들어 다음 선언을 고려하십시오.
[SerializableAttribute]
partial class Moon { }
[ObsoleteAttribute]
partial class Moon { }
다음 선언과 동일합니다.
[SerializableAttribute]
[ObsoleteAttribute]
class Moon { }
다음은 모든 부분 유형 정의에서 병합 된 것입니다.
XML 주석
인터페이스
일반 유형 매개 변수 속성
클래스 속성
회원
2. 또 다른 것은 중첩 된 부분 클래스가 부분적 일 수도 있습니다.
partial class ClassWithNestedClass
{
partial class NestedClass { }
}
partial class ClassWithNestedClass
{
partial class NestedClass { }
}
다음은 부분 클래스의 장점 중 일부 목록입니다.
읽고 이해하기 쉽도록 UI 디자인 코드와 비즈니스 로직 코드를 분리 할 수 있습니다. 예를 들어 Visual Studio를 사용하여 웹 응용 프로그램을 개발하고 새 웹 양식을 추가하면 "aspx.cs"및 "aspx.designer.cs"라는 두 개의 소스 파일이 있습니다. 이 두 파일은 부분 키워드와 동일한 클래스를 갖습니다. ".aspx.cs"클래스에는 비즈니스 로직 코드가 있고 "aspx.designer.cs"에는 사용자 인터페이스 제어 정의가 있습니다.
자동 생성 된 소스로 작업 할 때 소스 파일을 다시 만들지 않고도 클래스에 코드를 추가 할 수 있습니다. 예를 들어 LINQ to SQL로 작업하고 DBML 파일을 만듭니다. 이제 테이블을 끌어서 놓으면 designer.cs에 부분 클래스가 만들어지고 모든 테이블 열에는 클래스에 속성이 있습니다. 이 표에 UI 그리드에서 바인드 할 열이 더 필요하지만 데이터베이스 테이블에 새 열을 추가하지 않으려면 해당 열에 대한 새 특성을 가진이 클래스에 대해 별도의 소스 파일을 작성할 수 있습니다. 부분 수업이 되십시오. 따라서 데이터베이스 테이블과 DBML 엔터티 간의 매핑에 영향을 주지만 추가 필드를 쉽게 얻을 수 있습니다. 즉, 시스템 생성 코드를 망설이지 않고 직접 코드를 작성할 수 있습니다.
둘 이상의 개발자가 동시에 클래스의 코드를 작성할 수 있습니다.
큰 클래스를 압축하여 응용 프로그램을 더 잘 유지할 수 있습니다. 인터페이스 구현에 따라 여러 소스 파일을 작성할 수 있도록 여러 인터페이스가있는 클래스가 있다고 가정하십시오. 소스 파일에 부분 클래스가있는 인터페이스를 이해하고 유지 보수하기가 쉽습니다.
크기 / 복잡성이 큰 중첩 클래스가 포함 된 클래스가있을 때마다 클래스를 partial
하고 중첩 클래스를 별도의 파일에 넣습니다. [class name]. [nested class name] .cs 규칙을 사용하여 중첩 클래스가 포함 된 파일의 이름을 지정합니다.
다음 MSDN 블로그는 유지 관리를 위해 중첩 클래스와 함께 부분 클래스를 사용하는 방법을 설명합니다. http://blogs.msdn.com/b/marcelolr/archive/2009/04/13/using-partial-classes-with-nested-classes-for- maintenanceability.aspx
나는이 질문이 실제로 오래되었다는 것을 알고 있지만 부분 수업에 테이크를 추가하고 싶습니다.
개인적으로 부분 클래스를 사용하는 한 가지 이유는 프로그램, 특히 상태 시스템에 대한 바인딩을 만들 때입니다.
예를 들어, OpenGL은 상태 머신, 거기에 힙 모두 많은 방법이 있습니다 OpenGL을 비슷한 바인딩 내 경험에서, 그러나, 전 세계적으로 변경할 수 있습니다 방법은, 클래스는 쉽게 10,000 LOC를 초과 할 수 있습니다.
부분 수업은 나를 위해 이것을 분류 하고 신속하게 방법을 찾는 데 도움 이됩니다 .
부분 클래스는 주로 코드 생성기를 돕기 위해 도입되었으므로, 우리 (사용자)는 재생성 할 때마다 ASP.NET의 .designer.cs 클래스와 같이 생성 된 클래스에 대한 모든 작업 / 변경 사항을 잃어 버리지 않습니다. 코드 LINQ, EntityFrameworks, ASP.NET은 생성 된 코드에 부분 클래스를 사용하므로 부분 클래스와 메소드를 활용하여 생성 된 코드의 논리를 안전하게 추가하거나 변경할 수 있지만 부분 클래스를 사용하여 생성 된 코드에 항목을 추가하기 전에 매우 신중해야합니다. 빌드를 중단하면 쉬워 지지만 런타임 오류가 발생하면 최악입니다. 자세한 내용은 http://www.4guysfromrolla.com/articles/071509-1.aspx를 확인하십시오 .
답변에서 명시 적으로 찾을 수없는 두 가지 사용법에 주목합니다.
일부 개발자는 주석을 사용하여 클래스의 다른 "부분"을 구분합니다. 예를 들어, 팀은 다음 규칙을 사용할 수 있습니다.
public class MyClass{
//Member variables
//Constructors
//Properties
//Methods
}
부분 클래스를 사용하면 한 단계 더 나아가 섹션을 별도의 파일로 분할 할 수 있습니다. 일반적으로 팀은 각 파일에 해당 섹션을 접미사로 붙일 수 있습니다. 따라서 위의 내용은 MyClassMembers.cs, MyClassConstructors.cs, MyClassProperties.cs, MyClassMethods.cs와 같습니다.
다른 답변에서 언급했듯이, 클래스를 나눌 가치가 있는지 여부는 아마도이 경우 클래스의 크기에 달려 있습니다. 작 으면 하나의 마스터 클래스에 모든 것을 포함하는 것이 더 쉽습니다. 그러나 이러한 섹션이 너무 커지면 마스터 클래스를 깔끔하게 유지하기 위해 해당 내용을 별도의 부분 클래스로 이동할 수 있습니다. 이 경우의 규칙은 다음과 같이 섹션 제목 뒤에 "부분 클래스 참조"와 같은 말을 남기는 것입니다.
//Methods - See partial class
이것은 드물게 발생하지만 사용하려는 라이브러리의 두 함수간에 네임 스페이스 충돌이있을 수 있습니다. 단일 클래스에서는 대부분 이들 중 하나에 대해 using 절을 사용할 수 있습니다. 다른 경우에는 정규화 된 이름 또는 별칭이 필요합니다. 부분 클래스를 사용하면 각 네임 스페이스와 using 문 목록이 다르므로 두 함수 집합을 두 개의 개별 파일로 분리 할 수 있습니다.
using Library1 = The.Namespace.You.Need
또는 다음을 사용하여 네임 스페이스 이름 바꾸기와 같은 네임 스페이스 충돌을 해결하는 메커니즘이 있습니다.global::Root.Of.Namespace