2009-11-13 1 views
5

이 질문은 과 유사합니다. 내부 추상 클래스 외부 사용을 숨기는 방법은 다른데 동기가 다릅니다.공용 abstact 클래스의 서브 클래 싱을 같은 어셈블리의 형식으로 제한하여 보호 된 멤버가 내부 형식으로 형식이 지정되도록하는 방법

internal class InternalTypeA {...} 

public class PublicClass 
{ 
    private readonly InternalTypeA _fieldA; 

    ... 
} 

는 위의 잘 컴파일 : 여기에 내가 다음 시작 시나리오

입니다. 그러나 나는 기본 클래스를 추출해야한다는 결정하고 다음 쓰려고했습니다 :

public abstract class PublicBaseClass 
{ 
    protected readonly InternalTypeA _fieldA; 

    ... 
} 

그리고 이렇게 문제, 보호 된 멤버 어셈블리 외부에서 볼 수 있지만 내부 유형, 그래서 그것은하지 않습니다 엮다.

PublicBaseClass와 같은 어셈블리에있는 공용 클래스 만이 상속받을 수 있으므로 컴파일러에서 _fieldA가 어셈블리 외부에 노출되지 않도록하는 방법을 알려 주어야합니까?

또는 내가하고 싶은 일을 할 수있는 또 다른 방법이 있습니다. 공용 수퍼 클래스와 모든 기본 어셈블리 클래스가 모두 같은 어셈블리에 있고 해당 어셈블리의 내부 형식을 공용 ("보호 된") 코드?

public abstract class PublicBaseClass 
{ 
    private readonly InternalTypeA _fieldA; 

    protected object FieldA { get { return _fieldA; } } 

    ... 
} 

public class SubClass1 : PublicBaseClass 
{ 
    private InternalTypeA _fieldA { get { return (InternalTypeA)FieldA; } } 
} 

public class SubClass2 : PublicBaseClass 
{ 
    private InternalTypeA _fieldA { get { return (InternalTypeA)FieldA; } } 
} 

하지만 그건 추한 :

내가 지금까지 있었 단 생각은 ​​다음과 같다!

답변

5

CLR은 원하는대로 할 수있는 FamilyAndAssembly 접근성을 제공하지만 C#에서는 구문을 사용하지 않습니다.

해결 방법은 변수 필드를 내부로 만드는 것이고 부적절하게 액세스하지 못하도록 어셈블리의 코드를 신뢰해야합니다.

PublicBaseClass의 생성자를 내부로 만들 수도 있습니다. 따라서 어셈블리에서만 인스턴스를 생성 할 수 있습니다. 그렇게하면 클래스 만이 상속받을 수 있습니다 (클래스 자체가 공용 인 경우에도)

+1

네는 FamilyAndAssembly는 정확히 내가 원하는입니다. 내부 멤버를 사용하는 것이 위의 해킹보다 낫다는 것에 동의합니다. 왜 내가 그것을 생각하지 않았는지 궁금해. 아마 내가 너무 범위가 좁은 것을 싫어하기 때문일거야. 정보 주셔서 감사합니다! –

+0

Ay, 나도 꽤 짜증나지만, 불행히도 함께 살 수있는 뭔가가있다. ( – thecoop

0

가장 확실한 방법은 공용 인터페이스와 개인 클래스를 사용하는 것입니다. 리팩토링 기존 코드가 항상 옵션은 아닙니다. 이 변환의 어려움을 덜어주는 쉬운 방법 중 하나는 공용 추상 클래스를 인터페이스 대신 사용하고 정적 팩토리 메서드를 노출하는 것입니다.

예 :

public abstract class MyClass 
{ 
    public static MyClass New() 
    { return new InternalMyClass(); } 
} 

class InternalMyClass : MyClass 
{ } 
+0

InternalMyClass가 공용 유형이기 때문에이 접근 방식이 작동하지 않을 것이다. –