C # 부분 클래스를 사용하는 것이 언제 적절한가요?
누군가 내가 왜 그것을 사용하는지와 프로세스에서 얻을 수있는 이점에 대한 개요를 나에게 줄 수 있는지 궁금합니다.
부분 클래스의 가장 큰 사용은 코드 생성기 / 디자이너의 삶을 더 쉽게 만드는 것입니다. 부분 클래스를 사용하면 생성기가 생성해야하는 코드를 간단히 방출 할 수 있으며 파일에 대한 사용자 편집을 처리 할 필요가 없습니다. 마찬가지로 사용자는 두 번째 부분 클래스를 사용하여 새 멤버로 클래스에 주석을 달 수 있습니다. 이것은 관심사 분리를위한 매우 깨끗한 프레임 워크를 제공합니다.
그것을 보는 더 좋은 방법은 디자이너가 부분 수업 전에 어떻게 기능했는지를 보는 것입니다. 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
}
다른 답변 외에도 ...
나는 신 클래스를 리팩토링하는 데 디딤돌로 도움이된다는 것을 알았습니다. 클래스에 여러 책임이있는 경우 (특히 매우 큰 코드 파일 인 경우) 코드를 구성하고 리팩토링하기위한 첫 번째 패스로 1x 부분 클래스 당 책임을 추가하는 것이 좋습니다.
실제로 실행 동작에 영향을 미치지 않고 코드를 훨씬 더 읽기 쉽게 만들 수 있기 때문에 크게 도움이됩니다. 또한 책임을 쉽게 리팩토링하거나 다른 측면과 밀접하게 관련되어있는시기를 식별 할 수 있습니다.
그러나, 분명히 – 이것은 여전히 나쁜 코드입니다. 개발이 끝날 때 여전히 클래스 당 하나의 책임을 원합니다 ( 부분 클래스가 아닌 ). 그것은 단지 디딤돌입니다 :)
- 부분 클래스를 사용하는 다중 개발자 여러 개발자 가 동일한 클래스에서 쉽게 작업 할 수 있습니다.
- 코드 생성기 부분 클래스는 주로 코드 생성기에서 서로 다른 문제를 분리하여 사용합니다.
- 부분 메소드 부분 클래스를 사용하면 개발자가 메소드를 간단하게 정의하고 다른 개발자가이를 구현할 수있는 부분 메소드도 정의 할 수 있습니다.
부분 메소드 선언 만 코드는 메소드 선언으로 만 컴파일되며 메소드 구현이 존재하지 않는 경우 컴파일러는 해당 코드를 안전하게 제거 할 수 있으며 컴파일 시간 오류가 발생하지 않습니다.
포인트 4를 확인하려면 : winform 프로젝트를 만들고 Form1 생성자 뒤에이 줄을 포함시키고 코드를 컴파일하십시오.
partial void Ontest(string s);
다음은 부분 클래스를 구현할 때 고려해야 할 사항입니다.
- 부분 클래스의 각 부분에 부분 키워드를 사용하십시오.
- 부분 클래스의 각 부분 이름은 동일해야하지만 부분 클래스의 각 부분에 대한 소스 파일 이름은 다를 수 있습니다.
- 부분 클래스의 모든 부분은 동일한 네임 스페이스에 있어야합니다.
- 부분 클래스의 각 부분은 동일한 어셈블리 또는 DLL에 있어야합니다. 즉, 다른 클래스 라이브러리 프로젝트의 소스 파일에서 부분 클래스를 만들 수 없습니다.
- 부분 클래스의 각 부분은 동일한 접근성을 가져야합니다. (예 : 개인, 공개 또는 보호)
- 부분 클래스에서 클래스 또는 인터페이스를 상속하면 해당 부분 클래스의 모든 부분에서 상속됩니다.
- 부분 클래스의 일부가 봉인 된 경우 전체 클래스가 봉인됩니다.
- 부분 클래스의 일부가 추상 인 경우 전체 클래스는 추상 클래스로 간주됩니다.
한 가지 유용한 용도는 생성 된 코드를 동일한 클래스에 속하는 수작업 코드와 분리하는 것입니다.
예를 들어 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.
또 다른 가능한 용도는 둘 이상의 개발자가 서로 다른 장소에 저장된 동일한 클래스에서 작업 할 수 있다는 것입니다. 사람들은 웃을 수 있지만 때로는 소수 일 수 있다는 것을 결코 알지 못합니다.
Product1.cs
public partial class Product
{
//you are writing the business logic for fast moving product
}
Product2.cs
public partial class Product
{
// Another developer writing some business logic...
}
이해가 되길 바랍니다!
거대한 클래스를 사용하거나 팀에서 작업 할 때 가능한 한 모든 것을 최대한 깨끗하게 유지하십시오. 재정의하지 않고 편집하거나 항상 변경 내용을 커밋 할 수 있습니다.
부분 클래스의 주요 용도는 생성 된 코드입니다. WPF (Windows Presentation Foundation) 네트워크를 보면 마크 업 (XML)을 사용하여 UI를 정의합니다. 해당 마크 업은 부분 클래스로 컴파일됩니다. 자신 만의 부분 클래스로 코드를 작성합니다.
부분 클래스는 여러 파일에 걸쳐 있습니다.
How can you use the partial modifier on a C# class declaration?
부분적으로 클래스를 여러 파일로 물리적으로 분리 할 수 있습니다.
이것은 종종 코드 생성기에 의해 수행됩니다.
예
일반 C # 클래스를 사용하면 동일한 프로젝트에서 두 개의 개별 파일로 클래스를 선언 할 수 없습니다.
그러나 부분 수정자를 사용하면 가능합니다.
한 파일을 일반적으로 편집하고 다른 파일을 시스템에서 생성하거나 거의 편집하지 않는 경우에 유용합니다.
An Example will clear your concept.
class Program
{
static void Main()
{
A.A1();
A.A2();
}
}
//Contents of file A1.cs: C#
using System;
partial class A
{
public static void A1()
{
Console.WriteLine("A1");
}
}
//Contents of file A2.cs: C#
using System;
partial class A
{
public static void A2()
{
Console.WriteLine("A2");
}
}
Output
A1
A2
여기에 부분이 필요합니다.
If you remove the partial modifier, you will get an error containing this text: [The namespace '<global namespace>' already contains a definition for 'A'].
팁 : 이 문제를 해결하려면 부분 키워드를 사용하거나 클래스 이름 중 하나를 변경하십시오.
How does the C# compiler deal with partial classes?
위 프로그램을 분해하면 A1.cs 및 A2.cs 파일이 제거 된 것을 볼 수 있습니다.
클래스 A가 있음을 알 수 있습니다.
IL 디스어셈블러 따라서 : 클래스 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");
}
}
요약
부분 클래스는 특정 C # 프로그래밍 상황을 단순화 할 수 있습니다.
Windows Forms / WPF 프로그램을 만들 때 Visual Studio에서 자주 사용됩니다.
기계 생성 C # 코드는 별개입니다.
효과적인 리팩토링에 적합하지 않은 충분히 큰 클래스가있는 경우 클래스를 여러 파일로 분리하면 정리하는 데 도움이됩니다.
예를 들어 토론 포럼과 제품 시스템이 포함 된 사이트에 대한 데이터베이스가 있고 서로 다른 두 개의 제공자 클래스를 작성하지 않으려는 경우 (프록시 클래스와 동일하지 않음) 명확하게 할 수 있습니다. 다른 파일에 단일 부분 클래스를 만듭니다.
MyProvider.cs-핵심 로직
MyProvider.Forum.cs-포럼과 관련된 메소드
MyProvider.Product.cs-제품 메소드
사물을 정리하는 또 다른 방법 일뿐입니다.
또한 다른 사람들이 말했듯이 다음에 클래스를 다시 생성 할 때 추가 내용이 손상 될 위험을 발생시키지 않고 생성 된 클래스에 메소드를 추가하는 유일한 방법입니다. 템플릿 생성 (T4) 코드, ORM 등에 유용합니다.
사전 컴파일러 지시문의 대안으로.
프리 컴파일러 지시문 (즉, #IF DEBUG
)을 사용하는 경우 실제 릴리스 코드와 섞인보기 흉한 코드가 생깁니다.
이 코드를 포함 할 별도의 부분 클래스를 작성하고 지시문에 전체 부분 클래스를 랩핑하거나 해당 코드 파일이 컴파일러로 전송되는 것을 생략 할 수 있습니다 (효과적으로 동일하게 수행).
서비스 참조는 부분 클래스가 생성 된 코드를 사용자가 만든 코드와 분리하는 데 유용한 또 다른 예입니다.
서비스 참조를 업데이트 할 때 서비스 클래스를 덮어 쓰지 않고 "확장"할 수 있습니다.
내가 본 또 다른 용도는
데이터 액세스 로직에 관한 큰 추상 클래스 확장
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..
}
부분 클래스를 사용하면 소스 파일을 추가하기 만하면 적절하게 설계된 프로그램에 기능을 추가 할 수 있습니다. 예를 들어, 파일 가져 오기 프로그램은 파일을 처리하는 모듈을 추가하여 다른 유형의 알려진 파일을 추가 할 수 있도록 설계 될 수 있습니다. 예를 들어, 주 파일 형식 변환기에는 작은 클래스가 포함될 수 있습니다.
부분 공개 클래스 zzFileConverterRegistrar 이벤트 등록 (ByVal mainConverter as zzFileConverter) 서브 레지스터 전체 (ByVal mainConverter as zzFileConverter) 이벤트 등록기 (mainConverter) 엔드 서브 엔드 클래스
하나 이상의 파일 변환기 유형을 등록하려는 각 모듈에는 다음과 같은 내용이 포함될 수 있습니다.
부분 공개 클래스 zzFileConverterRegistrar Private Sub RegisterGif (ByVal mainConverter as zzFileConverter)는 나를 등록합니다. mainConverter.RegisterConverter ( "GIF", GifConverter.NewFactory)) 엔드 서브 엔드 클래스
주 파일 변환기 클래스는 "노출"되지 않으며, 추가 기능 모듈이 연결할 수있는 작은 스텁 클래스 만 노출합니다. 이름 충돌이 약간의 위험이 있지만 각 추가 기능 모듈의 "등록"루틴이 처리하는 파일 유형에 따라 이름이 지정된 경우 문제가되지 않습니다. 그러한 것들이 걱정된다면 등록 서브 루틴의 이름으로 GUID를 붙일 수 있습니다.
Edit/Addendum To be clear, the purpose of this is to provide a means by which a variety of separate classes can let a main program or class know about them. The only thing the main file converter will do with zzFileConverterRegistrar is create one instance of it and call the registerAll method which will fire the Register event. Any module that wants to hook that event can execute arbitrary code in response to it (that's the whole idea) but there isn't anything a module could do by improperly extending the zzFileConverterRegistrar class other than define a method whose name matches that of something else. It would certainly be possible for one improperly-written extension to break another improperly-written extension, but the solution for that is for anyone who doesn't want his extension broken to simply write it properly.
부분 클래스를 사용하지 않고 주 파일 변환기 클래스 내의 어딘가에 약간의 코드가있을 수 있습니다.
RegisterConverter ( "GIF", GifConvertor.NewFactory) RegisterConverter ( "BMP", BmpConvertor.NewFactory) RegisterConverter ( "JPEG", JpegConvertor.NewFactory)
그러나 다른 변환기 모듈을 추가하려면 변환기 코드의 해당 부분으로 이동하여 새 변환기를 목록에 추가해야합니다. 더 이상 필요하지 않은 부분 방법을 사용하면 모든 변환기가 자동으로 포함됩니다.
부분 클래스는 최근에 여러 개발자가 파일의 동일한 부분에 새로운 메소드가 추가 된 (Resharper에 의해 자동화 된) 하나의 파일에 여러 개발자가 추가하는 소스 제어에 도움이되었습니다.
git에 대한 이러한 푸시로 인해 병합 충돌이 발생했습니다. 새 도구를 완전한 코드 블록으로 사용하도록 병합 도구에 지시하는 방법을 찾지 못했습니다.
이와 관련하여 부분 클래스를 사용하면 개발자가 파일 버전을 고수 할 수 있으며 나중에 다시 병합 할 수 있습니다.
예 -
- MainClass.cs-필드, 생성자 등을 보유
- MainClass1.cs-개발자가 구현하는 새로운 코드
- MainClass2.cs-새로운 코드를위한 또 다른 개발자 클래스입니다.
대부분의 사람들 partial
은 생성 된 코드 파일이있는 클래스 또는 인터페이스에만 사용해야한다고 말합니다. 동의하지 않으며 여기에 이유가 있습니다.
하나의 예를 들어, ...는 C # System.Math 클래스에서의 모습을하자 그 클래스 . 70 개 이상의 메서드를 모두 동일한 단일 코드 파일에 넣지 않습니다. 유지하는 것은 악몽 일 것입니다.
각 수학 방법을 개별 부분 클래스 파일에 배치하고 모든 코드 파일을 프로젝트의 Math 폴더에 배치하면 조직이 훨씬 깔끔해집니다.
다양한 기능을 가진 다른 많은 클래스에서도 마찬가지입니다. 예를 들어 PrivateProfile API를 관리하기위한 클래스는 단일 프로젝트 폴더에서 깨끗한 부분 클래스 파일 세트로 분할하면 도움이됩니다.
개인적으로, 나는 대부분의 사람들이 "도우미"또는 "유틸리티"클래스를 각 메소드 또는 메소드 기능 그룹에 대한 개별 부분 파일로 분리합니다. 예를 들어 한 프로젝트에서 문자열 도우미 클래스에는 거의 50 개의 메서드가 있습니다. 그것은 심지어 지역을 사용하는 긴 다루기 힘든 코드 파일 일 것입니다. 각 방법마다 개별 부분 클래스 파일을 사용하여 유지 관리하는 것이 훨씬 쉽습니다.
부분 클래스를 사용하는 것을 조심 하고이 작업을 수행 할 때 프로젝트 전체에서 모든 코드 파일 레이아웃을 일관되게 유지하십시오. 클래스 공용 열거 형 및 클래스 전용 멤버를 폴더에있는 Common.cs 또는 유사한 이름의 파일에 배치하는 것과 같이 파일에 포함 된 부분 파일에만 한정되지 않는 한 파일 전체에 퍼뜨리는 대신.
클래스를 별도의 파일로 분할하면 현재 파일의 서로 다른 두 섹션을 동시에 볼 수있는 텍스트 편집기 스플리터 막대를 사용할 수 없게됩니다.
에서 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 문 목록이 다르므로 두 함수 집합을 두 개의 개별 파일로 분리 할 수 있습니다.
참고 URL : https://stackoverflow.com/questions/3601901/when-is-it-appropriate-to-use-c-sharp-partial-classes
'Programming' 카테고리의 다른 글
람다 식에서 속성 이름 검색 (0) | 2020.02.13 |
---|---|
Z- 색인의 최소값과 최대 값은? (0) | 2020.02.13 |
숭고한 텍스트가 탭당 두 칸을 들여 쓰도록하려면 어떻게합니까? (0) | 2020.02.13 |
“현재 중단 점에 도달하지 않습니다. (0) | 2020.02.13 |
파이썬에서 나쁜 / 잘못된 인수 조합에 대해 어떤 예외를 제기해야합니까? (0) | 2020.02.13 |