문제
C#을 사용하는 Visual Studio 2008에서 여러 클래스 및 소스 파일에서 코드를 공유하는 가장 좋은 방법은 무엇입니까?
클래스에 이미 의미있는 계층 구조가 있기 때문에 상속은 해결책이 아닙니다.
다른 클래스에서 원하는 코드를 삽입 할 수있는 C 포함 파일과 같은 깔끔한 기능이 있습니까?
편집하다:
좋아, 우리는 구체적인 예가 필요하다고 생각합니다 ...
도메인에는 수백 개의 클래스가 있습니다. 이제 이러한 수업 중 다수가 인쇄해야합니다. 인쇄를 처리하는 유틸리티 프린터 클래스가 있습니다. 인쇄중인 클래스에 의존하는 3 가지 인쇄 방법이 있다고 가정 해 봅시다. 인쇄 방법 (6 줄)을 호출하는 코드는 모든 다른 클라이언트 클래스 페이지에서 복사 및 붙여 넣기를 피하려고하는 것입니다.
사람들이 OP의 도메인에 대해 더 많이 알지 못한다고 가정하지 않으면 좋을 것입니다. 특히 그들이 맞지 않는 기술을 구체적으로 언급 할 때 ...
해결책
매우 다른 것들을 나타내는 수업에서 자주 사용하는 기능이 있다면 내 경험상 몇 가지 범주에 속해야합니다.
- 유틸리티 (예 : 문자열 서식, 구문 분석, ...)
- 크로스 절단 문제 (로깅, 보안 집행, ...)
유틸리티 유형 기능의 경우 별도의 클래스를 작성하고 비즈니스 클래스에 필요한 유틸리티 클래스를 참조하는 것을 고려해야합니다.
public class Validator
{
public bool IsValidName(string name);
}
class Patient
{
private Validator validator = new Validator();
public string FirstName
{
set
{
if (validator.IsValidName(value)) ... else ...
}
}
}
로깅 또는 보안과 같은 문제를 교차 절단하려면 조사하는 것이 좋습니다. 측면 지향 프로그래밍.
다른 의견에서 논의 된 printa vs. printb 예제와 관련하여, 그것은 공장 패턴에 대한 훌륭한 사례처럼 들립니다. IPRINT를 구현하는 IPRINT, CLASSER PRINTA 및 PRINTB를 정의하고 특정 페이지에 필요한 사항에 따라 IPRINT 인스턴스를 할당합니다.
// Simplified example to explain:
public interface IPrint
{
public void Print(string);
}
public class PrintA : IPrint
{
public void Print(string input)
{ ... format as desired for A ... }
}
public class PrintB : IPrint
{
public void Print(string input)
{ ... format as desired for B ... }
}
class MyPage
{
IPrint printer;
public class MyPage(bool usePrintA)
{
if (usePrintA) printer = new PrintA(); else printer = new PrintB();
}
public PrintThePage()
{
printer.Print(thePageText);
}
}
다른 팁
C에서와 마찬가지로 사전 처리기 지침을 통해 C# 클래스에 추가하려는 코드를로드 할 수는 없습니다.
그러나 인터페이스를 정의하고 해당 인터페이스의 확장 메소드를 선언 할 수 있습니다. 그런 다음 인터페이스를 수업에서 구현할 수 있으며 해당 클래스의 확장 방법을 호출 할 수 있습니다. 예를 들어
public interface IShareFunctionality { }
public static class Extensions
{
public static bool DoSomething(this IShareFunctionality input)
{
return input == null;
}
}
public class MyClass : Object, IShareFunctionality
{
public void SomeMethod()
{
if(this.DoSomething())
throw new Exception("Impossible!");
}
}
이렇게하면 기능을 재사용 할 수 있지만 해시가 파일을 포함 할 수 있다면 클래스의 개인 구성원에게 액세스 할 수 없습니다.
우리는 당신이하고 싶은 일에 대한 더 구체적인 예가 필요할 수 있습니까?
AC# 유틸리티 클래스가 작동합니다. 공통 코드의 중앙 레지스트리 (또는 vb.net 모듈 구성과 유사)와 같은 역할을합니다. 어떤 클래스에 특정하지 않은 코드가 포함되어야합니다. 그렇지 않으면 관련 클래스에 첨부되어 있어야합니다.
너 ~하지 않다 필요하지 않은 경우 소스 코드 복사를 시작하고 싶습니다. 복사.
소스가 상태를 유지할 필요가없는 한 정적 메소드가있는 정적 클래스를 사용하십시오.
static public class MySharedMembers {
static public string ConvertToInvariantCase(string str) {
//...logic
}
// .... other members
}
클래스가 동일한 네임 스페이스 인 경우 포함 아날로그 포함이 필요하지 않습니다. 다른 기능에 정의 된 클래스의 멤버를 호출하기 만하면됩니다.
동일한 네임 스페이스에 있지 않은 경우 idings 지시문에서 사용하려는 클래스의 네임 스페이스를 추가하면 위와 동일하게 작동해야합니다.
나는 질문에 혼란스러워합니다. 기본적인 OO 이해를 위해 노력해야하는 것 같습니다.
체크 아웃 연장 방법 : http://msdn.microsoft.com/en-us/library/bb383977.aspx
파일의 일부를 포함시키는 방법을 모르지만 우리가 자주하는 한 가지는 기존 파일을 추가하고 현재 위치에서 "링크"하는 것입니다. 예를 들어, 모든 프로젝트가 솔루션 디렉토리에서 언급하는 AssemblyInfo.cs 파일이 있습니다. 우리는 그것을 한 번 변경하고 모든 프로젝트는 동일한 파일을 참조하기 때문에 동일한 정보를 가지고 있습니다.
그렇지 않으면, 공통된 "공통"루틴에 대한 제안은 .NET에서 내가 생각해 낸 가장 좋은 것입니다.
나는 이미 "의미있는"구조로 당신이 의미하는 바를 확실하지 않지만, 이것은 당신이 기본 클래스 구현을 사용할 수있는 장소처럼 들립니다. C ++ 다중 상속만큼 "Verbose"는 아니지만, 일반적인 기능을 재사용하기 위해 Chained Base Class 구현을 사용하여 약간의 이점을 얻을 수 있습니다.
클래스 계층 구조를 보존하고 최소한 시각적으로 보존하고 필요에 따라 동작을 무시할 수 있습니다.
반복적 인 코드를 서비스로 가져옵니다. 반복 코드는 리팩토링을위한 여지가있을 수 있다는 단서입니다.
예를 들어, 인쇄하는 데 필요한 논리가 포함 된 "PrintingService"를 만듭니다. 그런 다음 인쇄 해야하는 클래스 가이 서비스에 종속성을 가질 수 있습니다 (생성자 또는 서비스가 필요한 메소드의 매개 변수를 통해).
이 라인을 따라 가지고있는 또 다른 팁은 기본 기능을위한 인터페이스를 작성한 다음 인터페이스를 사용하여 코드에 대한 코드를 사용하는 것입니다. 예를 들어, 사용자가 팩스, 이메일 또는 인쇄 할 수있는 보고서 수업이 많이있었습니다. 각각에 대한 메소드를 작성하는 대신 각각에 대한 서비스를 만들었고, 단일 output () 메소드가있는 인터페이스를 구현했습니다. 그런 다음 사용자가 원하는 출력의 종류에 따라 각 서비스를 동일한 방법으로 전달할 수 있습니다. 고객이 모뎀을 통해 팩스를 팩스로 팩스를 사용하기를 원했을 때, 동일한 인터페이스를 구현 한 새로운 서비스를 작성하는 문제 일뿐입니다.
솔직히 말해서 나는 Visual C#에 포함 된 것과 같은 것을 생각할 수 없으며 왜 그 기능을 원하는지 생각할 수 없습니다. 즉, 부분 클래스는 원하는 것과 같은 일을 할 수 있지만, "클래스에 대한 충돌은 이미 의미있는 계층 구조가 있습니다"요구 사항에 대한 충돌 일 수 있습니다.
많은 옵션, TT, Extension Method, Delegate 및 Lambda가 있습니다.